小程序wx.uploadFile踩坑

前端实现

小程序目前可以上传文件了,比如最常用到的会是图片的上传:

我们可以使用wx.chooseImage(OBJECT)实现

官方示例如下:

1
2
3
4
5
6
7
8
9
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths
}
})

小程序目前一次只能上传一张图片;

上传后通过wx.uploadFile(OBJECT) 可以将本地资源文件上传到服务器。

官方示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
wx.chooseImage({
success: function(res) {
var tempFilePaths = res.tempFilePaths
wx.uploadFile({
url: 'http://example.weixin.qq.com/upload', //仅为示例,非真实的接口地址
filePath: tempFilePaths[0],
name: 'file',
formData:{
'user': 'test'
},
success: function(res){
var data = res.data
//do something
}
})
}
})

后端实现

后端的实现我们使用最基本的Servlet进行基本的post和get操作就可以把文件存储下来;

核心代码如下,具体捕获到再进行其他处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(FileUploadServlet.class);
public FileUploadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
JsonMessage<Object> message = new JsonMessage<Object>();
EOSResponse eosResponse = null;
String sessionToken = null;
FileItem file = null;
InputStream in = null;
ByteArrayOutputStream swapStream1 = null;
try {
request.setCharacterEncoding("UTF-8");
//1、创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//2、创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//解决上传文件名的中文乱码
upload.setHeaderEncoding("UTF-8");
// 1. 得到 FileItem 的集合 items
List<FileItem> items = upload.parseRequest(request);
logger.info("items:{}", items.size());
// 2. 遍历 items:
for (FileItem item : items) {
String name = item.getFieldName();
logger.info("fieldName:{}", name);
// 若是一个一般的表单域, 打印信息
if (item.isFormField()) {
String value = item.getString("utf-8");
//进行业务处理...
}else {
if("file".equals(name)){
//进行文件存储....
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(swapStream1 != null){
swapStream1.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in != null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
PrintWriter out = response.getWriter();
out.write(JSONObject.toJSONString(message));
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

真机无法通过问题

用上面的方法调试后, 会发现在本机的开发者工具是可以通过的, 但一弄到真机上面去调试, 就会发现无法通过, 这大概会有两个原因:

  1. 没有使用真实的地址去调试, 真机调试需要用到https连接才可以通过, 因此需要先搭建一台服务器进行模拟, 不能使用本地的地址;
  2. 服务器不支持TSL1.2, ios对于加密策略比较谨慎, 需要对https服务的支持TSL1.2才可以, 可以使用这个地址来测试服务器支不支持TSL1.2,地址如下:https://www.ssllabs.com/ssltest/index.html

PS:上面的写法也可以改为servlet的getParameter

hyhcoder wechat
扫码关注我的个人订阅号