解决小程序图片上传问题
解决小程序图片上传问题
【项目需求】:在小程序中点击按钮,上传图片,并显示相应图片。之前写过在Vue上的图片上传,但是存在一些小问题,待改进。
【遇到的问题】:
本来微信官方文档已经提供了 wx:chooseImage
接口,只需要调用就可以很快实现图片上传显示。
但是,这里有一个非常严重的问题。使用wx:chooseImage
拿到的图片资源是一个临时图片(路径前缀为:wxfile://tmp 或者 http://tmp),如果小程序关闭,在微信开发者工具上问题不是特别明显,但是在真机上测试图片资源是显示不出来的,变成了一张空白图片。
百度一通,个人总结就是这个临时路径,在本次小程序启动期间是可以正常使用的,但是小程序关闭了,临时图片就会被回收清理。
【解决方法】:
这个结果显然不是我想要的,所以我目前能想到的方法就是把这个图片资源上传到服务器上。
【解决步骤】:
我的前端使用的小程序,后端使用的SpringMVC。
小程序:
wxml文件
<view class="weui-uploader__input-box"><view class="weui-uploader__input" bindtap="chooseImage"></view>
</view>
<image class="weui-uploader__img" src='{{url}}' mode="aspectFill" />
JS文件
const upload = require('../../utils/upload.js')
Page({data: {url:'',},chooseImage: function (e) {var that = this;wx.chooseImage({sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有success: function (res) {// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片let tempFilePaths = res.tempFilePathsupload("/shop/uploadImg",tempFilePaths).then(res=>{let data = JSON.parse(res.data)console.log(data)that.setData({url:`http://172.20.10.7:8080/upload/${data.message}`})})}})},
})
这里我自己封装了一个文件上传的方法 upload.js
// 上传文件网络请求
/*** path: 接口地址(相对)* tempFilePaths: 上传文件数组 []* data:携带的数据对象 {}*/
module.exports = function(path,tempFilePaths,data){return new Promise((resolve,reject) => {wx.uploadFile({url: '自己服务器的接口地址', //接口地址filePath: tempFilePaths[0],name: 'file',formData: data,//这里有一个坑!巨坑!//成功返回的data数据是一个字符串,所以要自己转换成JSON数据success: resolve, // 请求失败执行fail操作fail: () => {reject()wx.showModal({showCancel: false,title: '服务器繁忙'})}})})
}
服务器端有一个问题需要注意的是,上传图片的位置我是放在同级项目发布路径下的,和项目不是在一个文件夹下。因为我之前直接放在项目发布路径下,发现访问不了文件资源,所以就把保存的文件资源拿出来了。
这里,我借鉴了这位博主的方法:解决Tomcat无法访问webapp下静态资源的问题
后台Controller层:
package com.wyf.controller;import java.io.File;
import java.util.UUID;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;import com.wyf.po.Result;@Controller
public class UploadFileCon {/*** 图片上传,解决小程序端临时图片问题* * @param request* @param response* @return*/@RequestMapping("/shop/uploadImg")@ResponseBodypublic Result uploadImg(HttpServletRequest request, HttpServletResponse response) {MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;MultipartFile multipartFile = req.getFile("file");// 获取上传文件原始名String originalName = multipartFile.getOriginalFilename();// 设置上传文件的保存路径String realPath = "G:/安装包/Tomcat/安装包/Tomcat 7.0/webapps/upload";String newFileName = "";try {File dir = new File(realPath);// 如果保存文件的地址不存在,就先创建目录if (!dir.exists()) {dir.mkdir();}// 使用UUID重新命名上传的文件名 + 文件的后缀名newFileName = "shop_" + UUID.randomUUID() + originalName.substring(originalName.lastIndexOf("."));File file = new File(realPath, newFileName);// 使用multipartFile接口的方法上传文件到指定位置multipartFile.transferTo(file);return new Result(true, newFileName);} catch (Exception e) {e.printStackTrace();return new Result(false, "操作异常");}}
}
我这里定义了一个Result类,主要用于给前端返回数据。
文件上传的位置:
为了实现访问,还需要定义xml文件,否则图片资源无法访问。
添加如下代码,docBase为自己的路径地址
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="G:\安装包\Tomcat\安装包\Tomcat 7.0\webapps\upload" reloadable="true"> </Context>
最后出来的效果就是下面这样的,可以直接访问服务器上的资源了。