上传:
官方文档: wx.uploadFile(OBJECT) 将本地资源上传到开发者服务器
客户端发起一个 HTTPS POST 请求,其中 content-type
为 multipart/form-data
一般先获取到一个本地资源的临时文件路径后,再通过此接口将本地资源上传到开发者服务器
如上可以看出: 小程序文件上传是使用wx.uploadFile发起的post请求
一般情况的资源请求是使用wx.request()来发起的, 而上传功能是使用wx.uploadFile发送POST请求来实现的
获取本地文件的路径:
wx.chooseImage获取的是本地图片资源
wx.chooseVideo 获取的是本地视频资源
如下视频上传为例:
// 文件上传
uploadFile: function() {
wx.chooseVideo({ // 打开本地磁盘目录, 选择上传文件
success : function(res) {
var path = res.tempFilePath; // 上传文件的临时目录
wx.uploadFile({
url: 'http://127.0.0.1:4040/upload',
filePath: path,
name: 'up_file',
header: {
"Content-Type": "multipart/form-data"
},
formData: {
userId: 123456, //可附加一些信息
videoName : "myVideoName.mp4"
},
success: function (res) {
console.log("成功: ");
console.log(res);
},
fail: function (res) {
console.log("失败");
},
complete: function (res) {
console.log("上传结束");
}
});
}
})
},
-
url 填写的是开发者服务器的接口 -- Controller的方法
-
header中填写content-type : multipart/form-data
-
formDate中填写额外的信息, 比如用户标识,视频名称等, 后台通过request取出, 感觉相当于header中的属性
-
wx.uploadFile()会返回一个对象, 此对象监听上传的情况, 可根据此对象做消息提示(如下面的下载消息提示)
后台接收:
@RequestMapping(value="/upload", method=RequestMethod.POST)
public void uploadPicture(HttpServletRequest request, HttpServletResponse response,
MultipartFile file) throws Exception {
request.setCharacterEncoding("utf-8"); //设置编码
// 构建一个上传的文件的 存放路径
String path = request.getServletContext().getRealPath("/");
path = path.replace("webapp\\", "") + "resources\\static\\upload_file";
File dir = new File(path);
if (!dir.exists()) { // 如果没有, 则创建文件夹
dir.mkdir();
}
MultipartHttpServletRequest req =(MultipartHttpServletRequest)request; // 转换request
MultipartFile multipartFile = req.getFile("up_file"); // 获得上传文件
String videoName = request.getParameter("videoName");
File dest = new File(dir, videoName);
multipartFile.transferTo(dest); // 写入目的文件夹
}
值得注意的是, 这个创建文件的路径, 我先获得项目站点路径, 再拼凑出目的路径(如上面的path)
MultipartHttpServletRequest 用于获得上传文件, 根据的是客户端上传文件的 "名称" wx.uploadFile中的name属性
MultipartFile用来处理上传文件
下载:
wx.downloadFile(OBJECT)
下载文件资源到本地,客户端直接发起一个 HTTP GET 请求,返回文件的本地临时路径
给到要下载的文件url就行了
Page({
data: {
img_l: '' // 页面中写一个image组件, src的值为img_l
},
down_file: function() {
var _this = this;
const downloadTask = wx.downloadFile({
url: 'http://127.0.0.1:4444/pic/1.gif', // 此为我服务器上的静态资源
success: function (res) { // 服务器响应回调
if (res.statusCode === 200) {
_this.setData({
img_l: res.tempFilePath // res.tempFilePath是临时路径, 但是可用于 在页面上预览
})
}
}
})
// 显示提示消息
wx.showToast({
title: '正在保存...',
icon: 'loading',
duration: 10000
});
// 监听下载进度, 这个函数根据下载进度重复执行, 直到下载完成
downloadTask.onProgressUpdate((res) => {
if (res.progress == 100) { // 当下载的进度为100时, 则表示下载完成
setTimeout(function() { // 完成1秒后执行隐藏(保证至少1秒的显示提示)
wx.hideToast();
}, 1000);
}
console.log('下载进度 : ', res.progress)
console.log('已经下载的数据长度 : ', res.totalBytesWritten)
console.log('预期需要下载的数据总长度 : ', res.totalBytesExpectedToWrite)
})
}
})
- wx.downloadFile()会返回一个对象, 这个对象可以监听下载的进程
- 所以先使用一个变量保存const downloadTask = wx.downloadFile()
- 这里做了一个下载提示消息wx.showToast, 当下载完成后, 经过1秒, 将消息提示隐藏
- 使用wx.hideToast的时候, 需要保证它与wx.showToast同级才能有效
- 其实下载过程中, 不需要在开发者服务器中写任何代码就能执行下载
这里是用图片为示例, 视频音频也完全一样的操作, 换一下资源即可:
url: 'http://127.0.0.1:4444/vdo/d.mkv'
url: 'http://127.0.0.1:4444/aud/ybwgkn.mp3'
记录一下:
本来这个mp3是中文名称"http://127.0.0.1:4444/aud/一百万个可能.mp3",
但是测试时会报错:Invalid character found in the request target, 意思是说在请求中有无效的字符, 也就是请求中的中文无效
所以我就将音乐的中文名称换成了字母名称, 这样就可以了, 如果不改中文名称呢