微信小程序开发技巧总结(二) -- 文件的选取、移动、上传和下载

1.不同类型文件的选取

1.1 常用的图片 视频

对于大部分开发者来说,需要上传的文件形式主要为图片,微信为此提供了接口。

wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success (res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths
}
})

其次为视频文件的选取,微信也为此提供了接口。

wx.chooseVideo({
sourceType: ['album','camera'],
maxDuration: 60, //视频长度 单位 s
camera: 'back', //选取前置 摄像 还是 后置 摄像
success(res) {
console.log(res.tempFilePath)
}
})

也为其提供了视频和图片的二合一接口,这个接口不建议调用,图片和视频的上传建议区分开。

wx.chooseMedia({
count: 9,
mediaType: ['image','video'],
sourceType: ['album', 'camera'],
maxDuration: 30,
camera: 'back',
success(res) {
console.log(res.tempFilePath)con
console.log(res.size)
}
})

这几个接口调用成功的回调函数中,都返回的是文件在文件在本机中的路径。

res.tempFilePath

这是一个 数组,存放着选择的所有文件的路径,用于上传。

1.2 其余形式各种文档

那么如果是想要在小程序中上传 doc、pdf、ppt 等类型的文件怎么处理?首先要注意的是微信小程序并没有给用户提供文件管理器接口。

开发者:我想要个文件管理器接口!

官方:不,你不想

聪明的开发者他没有办法,只能另辟蹊径。微信提供了一个选择客户端会话文件的方法。

wx.chooseMessageFile({
success(res){
console.log(res.tempFilePath)
}
})

与上面两个接口相同,返回的也是文件在本地的存储路径,但是不同的是,这个接口可以选取全部的文件类型。

开发者如果想要上传非图片和视频内容的话,需要两步走。

  1. 打开微信文件传输助手,将想要上传的文件发送到文件传输助手
  2. 在小程序中调用这个接口,选择文件传输助手,从会话中选择想要上传的文件。

2.文件的上传

2.1 uploadFile方法

所有的文件都是以字节流的形式进行上传,所以上传形式并没有什么本质区别,都是调用相应的接口进行上传。

小程序端写法如下:

wx.uploadFile({
url: '你的服务器函数地址', //仅为示例,非真实的接口地址
filePath: '需要上传的文件路径', //res.tempFilepaths
name: 'file', // 文件对应的key ,默认 为 file
formData: {
'user': 'test'
}, //上传额外携带的参数
success (res){
const data = res.data
//do something
}
})

2.2 服务器端如何处理上传的文件

服务端如何接受文件的上传?仅展示Java方式(SpringBoot 框架)

@Controller
@ResponseBody
public class FileController {
//文件上传控制类,是核心配置类,Win <->Linux
@RequestMapping(value = "/upload/images")
public String uploadimages(HttpServletRequest request,@RequestParam("file") MultipartFile file, @RequestParam("user") String user) throws IOException {
//更换服务器,这个值也需要修改
//图片上传写法
//type 是上传图片的类型
if(!file.isEmpty()){
//文件不为空
//String path = "E:"+File.separator+"images"+File.separator+type; // this is windows method
String path = "/share"+File.separator+"images"+File.separator+type;
// this is Linux method
String filename = file.getOriginalFilename();
File filepath = new File(path,filename);//新建文件存储路径
System.out.println(filepath);
if(!filepath.getParentFile().mkdirs()){
filepath.getParentFile().mkdirs();
}
file.transferTo(new File(path+File.separator+filename));
//想要返回可直接访问的链接还要配置 映射,具体请看下面链接
return "你的IP地址"+"/images/"+type+"/"+filename;
}else {
return "error";
}
}
}

配置访问映射

文件访问映射

2.3 云开发文件上传

微信小程序支持云开发,其文件上传接口有一些差异,但是不需要自己再构建后台。

wx.cloud.uploadFile({
cloudPath: 'file/' + '你的文件名字(带格式后缀)', // 在云端存储的路径
filePath: '', // 就是选择文件返回的路径
}).then(res => {
// get resource ID
console.log(res.fileID)
}).catch(error => {
// handle error
})

我们可以根据返回的fileID 置换 真实的文件访问地址。

其置换方式参见官方文档:

wx.cloud.getTempFileURL({
fileList: ['cloud://xxx', 'cloud://yyy'],
success: res => {
// get temp file URL
console.log(res.fileList)
},
fail: err => {
// handle error
}
})

TIPS:关于云开发文件上传的建议

  1. 如果没有保密需求,为了方便后续开发,存储到数据库中的最好是可以直接访问的文件链接。
  2. 置换真实文件地址,不要每次上传一次文件就置换一次,先把返回的fileID 存放在数组中,到该事务所有上传完成后,再使用fileID 数组置换真实文件访问链接数组。
  3. 要考虑文件名重复的可能,建议使用时间戳在 wx.cloud.uploadFile 中的 cloudPath 中对存储到云环境中的文件命名进行格式化。

总的来说就是先上传文件,再向数据库中写入记录。

2.4 多文件同时上传的处理方式

uploadFile 每次只能上传一个文件

如何处理这个问题?

A.不考虑文件的上传次序问题,可以采用遍历上传的方式,采用精确的时间戳和遍历index对文件名进行格式化。通过定时触发检测函数判断是否全部上传完成。这种方式考虑的是并发能力。

upSeveralfiles() {
wx.showLoading({
title: '上传中~',
mask: true
})
var that = this;
var timecode = sev.vcode(new Date()); // 这是时间戳编码函数
var files = this.data.fileList; // 这是 选择文件中返回的 res.tempFilePath 数组
var len = files.length;
var i = 0;
for (i = 0; i < len; i++) {
var str = files[i].name;
wx.cloud.uploadFile({
cloudPath: 'file/' + '(' + sev.getformatTime(new Date()) + ')' + str,
filePath: files[i].path,
success(res) {
console.log(res)
that.setData({
cloudlist: that.data.cloudlist.concat([res.fileID]), })
// cloudlist 是存放 文件链接置换id 的数组 , 非云开发存储的就是真实可访问的链接数组
// 如果使用的不是云开发 那么 可以返回真实的 访问地址
},
fail(res) {
console.log(res)
}
})
}
// 使用定时器检测文件是否全部上传完成 , 并 判断是否进行下一步 操作
var timer = setInterval(function () {
if (that.data.cloudlist.length == len) {
// 只有全部上传成功了 长度才会相等
clearInterval(timer);
// 继续执行下一步 ,根据 cloudlist 置换真实地址 并存放到数据库
// 如果使用的非云开发,那么就继续执行 存储至数据库的操作
}
}, 1000)
}

补充文件编码函数 sev.js 中的根据时间编码部分 , 可以根据实际流量自定义。

function getformatTime(date) {
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate() var hour = date.getHours()
var minute = date.getMinutes()
var second = date.getSeconds() return [year, month, day].map(formatNumber).join('-');
};

B.考虑文件的上传次序问题,采用回调方式进行文件上传(更推荐使用这种方式)

data: {
fileList: [],
realList: [],//云端地址链接列表
fileid: 0,
},
upSeveralfiles() {
var that = this;
var files = this.data.fileList; // 这是 选择文件中返回的 res.tempFilePath 数组
var len = files.length;
var uid = this.data.fileid;
wx.uploadFile({
url: '你的服务器文件接收函数请求地址',
name: 'file',
filePath: files[uid],
header: {
"Content-Type": "multipart/form-data"
},
success(res) {
that.setData({
fileid: uid + 1,
realList: that.data.realList.concat([res.data])
}, () => {
if (that.data.fileid == len) {
// 上传完成 ,执行下一步操作 } else {
//上传完一个文件 递归执行 下次上传
that.upSeveralfiles();
}
})
}, fail(res) {
console.log(res.data)
}
}) },

以上是提供的两种思路 , 无论是不是云开发 , 两种思路都是共通的,适用于多文件上传.

3.文件的下载

这个地方唯一值得注意的是云开发的一种下载方式 可以通过fileID进行download , 当然只能下载存储在自己云环境中的文件.

wx.cloud.downloadFile({
fileID: '',
success: res => {
console.log(res.tempFilePath)
},
fail: err => {
}
})
wx.downloadFile({
url: '', //仅为示例,并非真实的资源
success (res) {
//res.tempFilePath
})

下载进度监控 , 用于下载进度条绘制等功能实现

const downloadTask = wx.cloud.downloadFile({ *** }) // wx.downloadFile 同理
downloadTask.onProgressUpdate((res) => {
//res.progress 为下载进度
})

下载下来的文件支持直接打开,就像是在微信聊天中打开一样,需要下载插件。

其使用方式为:

wx.openDocument({
filePath: res.tempFilePath //为文件路径 非数组 , 可使用回调函数 success 等
})

4.文件的移动

这个一般情况下是用不到的, 也不建议使用移动文件的方法作为功能实现手段 ,必然有更好的替代方式,比如修改数据库路径 和 真实文件路径的映射, 效率更高一些.

这里仅讲云开发移动文件方式。

const cloud = require('wx-server-sdk')
const fs = require('fs')
const path = require('path') cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
}) exports.main = async (event, context) => {
const fileStream = fs.createReadStream(path.join(__dirname, 'demo.jpg'))
//这个可以读取 云存储 中的文件 , 所谓删除 就是复制 然后 删除原位置文件
return await cloud.uploadFile({
cloudPath: 'demo.jpg',
fileContent: fileStream,
})
}

具体开发文档

建议在数据库中修改映射路径最好。

需要小程序开发的请联系我QQ : 1025584691

微信小程序开发技巧总结(二) -- 文件的选取、移动、上传和下载的更多相关文章

  1. 微信小程序开发日记——高仿知乎日报(上)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...

  2. 微信小程序开发:学习笔记[8]——页面跳转及传参

    微信小程序开发:学习笔记[8]——页面跳转及传参 页面跳转 一个小程序拥有多个页面,我们可以通过wx.navigateTo推入一个新的页面.在首页使用2次wx.navigateTo后,页面层级会有三层 ...

  3. 微信小程序开发技巧及填坑记录

    以下是自己在开发过程中遇到的坑和小技巧,记录以下: 1.出现了 page[pages/XXX/XXX] not found.May be caused by :1. Forgot to add pag ...

  4. 微信小程序开发中的二三事之网易云信IMSDK DEMO

    本文由作者邹永胜授权网易云社区发布. 简介 为了更好的展示我们即时通讯SDK强悍的能力,网易云信IM SDK微信小程序DEMO的开发就提上了日程.用产品的话说就是: 云信 IM 小程序 SDK 的能力 ...

  5. 微信小程序开发教程(二)创建第一个微信小程序

    在安装完“微信Web开发者工具”之后,通过开发者的微信扫码进入后,如图. 点击“添加项目”,填入之前获得的AppID(无AppID可忽略),输入项目名称“Hello WXapplet”,选定本地文件夹 ...

  6. 微信小程序开发笔记(二)

    一.前言 继承上一篇所说的,有了对微信小程序的基础概念后,这边将会示范动手做一个小程序,在动手的过程中我们可以更快的熟悉小程序里面的架构和开发流程. 二.小程序的设计 这次要做的是一个猜数字的程序,程 ...

  7. 微信小程序基于腾讯云对象存储的图片上传

    在使用腾讯云对象存储之前,公司一直使用的是传统的FTP的上传模式,而随着用户量的不断增加,FTP所暴露出来的问题也越来越多,1.传输效率低,上传速度慢.2.时常有上传其他文件来攻击服务器,安全上得不到 ...

  8. 微信小程序开发系列(二)小程序的全局文件

    其实你已经知道了小程序的文件结构 上一节讲到,小程序的页面由三部分组成: 视图(.wxml).逻辑(.js).样式(.wxss). 我们这次重新展开文件结构: 小程序用到的文件类型只有四种,正如你所看 ...

  9. 微信小程序开发技巧总结 (一)-- 数据传递和存储

    结合自己在平时的开发中遇到的各种问题,和浏览各种问题的解决方案总结出一些自己在日常开发中常用的技巧和知点,希望各位不吝斧正. 1.短生命周期数据存储 以小程序启动到彻底关闭为周期的的数据建议存储在ap ...

随机推荐

  1. Vuex实践(下)-mapState和mapGetters

    Vuex系列文章 <Vuex实践(上)> <Vuex实践(中)-多module中的state.mutations.actions和getters> <Vuex实践(下)- ...

  2. 七种武器:JavaScript 新特性闪亮登场

    JavaScript(或ECMA Script) 是一门不断发展的语言,有许多关于如何前进的建议和想法.TC39(技术委员会39)是负责定义JS标准和特性的委员会,今年他们非常活跃.以下是目前处于&q ...

  3. Spring学习记录3——Spring AOP

    SpringAOP基础 AOP简介: AOP是Aspect Oriented Programing的简称,翻译为“面向切面编程”.它适用于具有横切逻辑的应用场合,如性能检测,访问控制,事务管理及日志记 ...

  4. Callable接口用法

    注意点:FutureTask是Runnable的实现类,它的构造器可以传Callable接口的实现类. 例子如下: class MyThread implements Callable<Inte ...

  5. git查看远程仓库和本地的区别

    git diff 你可以用 git diff 来比较项目中任意两个版本的差异. $ git diff master..test 上面这条命令只显示两个分支间的差异,如果你想找出 master , te ...

  6. 使用RobotFramework的JavaRemoteLibrary

    终于被迫使用了Java的远程接口库(为了同时使用Java和python的用例库,且为了在pybot下跑速度能快一些),路途比实际想的要坎坷,记录下来. 远程库的原理在前边一篇文章中记录过: http: ...

  7. playbooks框架与子文件编写规范

    Test Playbooks框架 ​ 详细目录testenv文件 ​ 主任务文件main.yml ​ 任务入口文件deploy.yml ​ Ansible连接playbooks需要添加ssh协议认证 ...

  8. 02.flask-script

    网址:https://pypi.org/project/Flask-Script/ 文档:https://flask-script.readthedocs.io/en/latest/ 1.安装 2.新 ...

  9. Scrapy持久化(items+pipelines)

    一.items保存爬取的文件 items.py import scrapy class QuoteItem(scrapy.Item): # define the fields for your ite ...

  10. item方法

    class Person: def __init__(self, name, age): self.name = name self.age = age def __getitem__(self, i ...