解决小程序图片上传问题

【项目需求】:在小程序中点击按钮,上传图片,并显示相应图片。之前写过在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.tempFilePaths
        upload("/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")
	@ResponseBody
	public 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类,主要用于给前端返回数据。

文件上传的位置:
解决小程序图片上传问题_第1张图片
为了实现访问,还需要定义xml文件,否则图片资源无法访问。
解决小程序图片上传问题_第2张图片解决小程序图片上传问题_第3张图片

添加如下代码,docBase为自己的路径地址

<?xml version="1.0" encoding="UTF-8"?> 
<Context docBase="G:\安装包\Tomcat\安装包\Tomcat 7.0\webapps\upload" reloadable="true"> </Context>

最后出来的效果就是下面这样的,可以直接访问服务器上的资源了。
解决小程序图片上传问题_第4张图片

你可能感兴趣的:(小程序,前端)