微信小程序上传图片(附后端代码)

几乎每个程序都需要用到图片。
在小程序中我们可以通过image组件显示图片。

当然小程序也是可以上传图片的,微信小程序文档也写的很清楚。

上传图片

首先选择图片

通过wx.chooseImage(OBJECT)实现

官方示例代码

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

图片最多可以选择9张, 也可以通过拍摄照片实现,当选择完图片之后会获取到图片路径, 这个路径在本次启动期间有效。
如果需要保存就需要用wx.saveFile(OBJECT)

上传图片

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

原理就是客户端发起一个 HTTPS POST 请求,其中 content-type为 multipart/form-data。

官方示例代码

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
      }
    })
  }
})

示例代码

看完了官方文档, 写一个上传图片就没有那么麻烦了,下面是真实场景的代码

import constant from '../../common/constant';
Page({
  data: {
    src: "../../image/photo.png",  //绑定image组件的src
     //略...
  },
  onLoad: function (options) {
      //略...
  },
  uploadPhoto() {
    var that = this;
    wx.chooseImage({
      count: 1, // 默认9
      sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
        var tempFilePaths = res.tempFilePaths;
        upload(that, tempFilePaths);
      }
    })
  }
})

function upload(page, path) {
  wx.showToast({
    icon: "loading",
    title: "正在上传"
  }),
    wx.uploadFile({
      url: constant.SERVER_URL + "/FileUploadServlet",
      filePath: path[0],
      name: 'file',
      header: { "Content-Type": "multipart/form-data" },
      formData: {
        //和服务器约定的token, 一般也可以放在header中
        'session_token': wx.getStorageSync('session_token')
      },
      success: function (res) {
        console.log(res);
        if (res.statusCode != 200) {
          wx.showModal({
            title: '提示',
            content: '上传失败',
            showCancel: false
          })
          return;
        }
        var data = res.data
        page.setData({  //上传成功修改显示头像
          src: path[0]
        })
      },
      fail: function (e) {
        console.log(e);
        wx.showModal({
          title: '提示',
          content: '上传失败',
          showCancel: false
        })
      },
      complete: function () {
        wx.hideToast();  //隐藏Toast
      }
    })
}

后端代码

后端是用java写的,一开始的时候,后端开始用了一些框架接收上传的图片,出现了各种问题,后来使用了纯粹的Servlet就没有了问题, 把代码贴出来省的以后麻烦了。

注意: 代码使用了公司内部的框架,建议修改后再使用

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");
                    if("session_token".equals(name)){
                        sessionToken = value;
                    }
                }else {
                    if("file".equals(name)){
                        file = item;
                    }
                }
            }
            //session校验
            if(StringUtils.isEmpty(sessionToken)){
                message.setStatus(StatusCodeConstant.SESSION_TOKEN_TIME_OUT);
                message.setErrorMsg(StatusCodeConstant.SESSION_TOKEN_TIME_OUT_MSG);
            }
            String userId = RedisUtils.hget(sessionToken,"userId");
            logger.info("userId:{}", userId);
            if(StringUtils.isEmpty(userId)){
                message.setStatus(StatusCodeConstant.SESSION_TOKEN_TIME_OUT);
                message.setErrorMsg(StatusCodeConstant.SESSION_TOKEN_TIME_OUT_MSG);
            }
            //上传文件
            if(file == null){
            }else{
                swapStream1 = new ByteArrayOutputStream();

                in = file.getInputStream();
                byte[] buff = new byte[1024];
                int rc = 0;
                while ((rc = in.read(buff)) > 0) {
                    swapStream1.write(buff, 0, rc);
                }

                Usr usr = new Usr();
                usr.setObjectId(Integer.parseInt(userId));

                final byte[] bytes = swapStream1.toByteArray();

                eosResponse= ServerProxy.getSharedInstance().saveHeadPortrait(usr, new RequestOperation() {

                    @Override
                    public void addValueToRequest(EOSRequest request) {
                        request.addMedia("head_icon_media", new EOSMediaData(EOSMediaData.MEDIA_TYPE_IMAGE_JPEG, bytes));
                    }
                });

                // 请求成功的场合
                if (eosResponse.getCode() == 0) {
                    message.setStatus(ConstantUnit.SUCCESS);
                } else {
                    message.setStatus(String.valueOf(eosResponse.getCode()));
                }
            }
        } 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);
    }

}

更多精彩请关注微信公众账号likeDev

时间: 2025-01-19 01:27:08

微信小程序上传图片(附后端代码)的相关文章

微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决_JavaScript

微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决 微信小程序上传图片的时候,如果是多图片上传,一般都是直接用一个循环进行wx.uploadFile 这个在电脑上面测试与苹果手机上面都不会有什么问题 但当用安卓测试的时候,你会发现小程序会提示一个the same task is working wx.uploadFile不能并行,因为wx.uploadFile是一个异步函数,所以循环的时候在安卓手机上会出现并行 解决的方法 做一个上传完的

使用微信小程序开发前端【快速入门】_javascript技巧

前言 2016年9月22日凌晨,微信官方通过"微信公开课"公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真正收到内测邀请的公众号据说只有200个. 虽然内测名额十分稀少,但依赖中国广大开发者的破解和分享精神,在网络上很快出现了开发工具的破解版本和API文档.然而可能是微信的妥协或者早已预料,9月24日微信官方发布了不需要破解就可以使用的微信小程序开发者工具和文档,对于费劲心思破解完的开发者来说应该瞬间整个人都不好

微信小程序Server端环境配置

源码地址:https://github.com/Tinywan/PHP_Experience   主要内容:1. SSL免费证书申请步骤2. Nginx HTTPS 配置3. TLS 1.2 升级过程   微信小程序要求使用 https 发送请求,那么Web服务器就要配置成支持 https,需要先申请SSL证书 小程序也要求 TLS(传输层安全协议)的版本至少为 1.2,在配置好 https之后,如果 TLS 的版本较低,就涉及到升级问题 所以 Server端环境配置的主要步骤: 申请 SSL

微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例_javascript技巧

本文介绍了微信小程序的开发,主要包括图片.录音.音频播放.音乐播放.视频.文件,具体如下: 图片: wx.chooseImage(OBJECT) 从本地相册选择图片或使用相机拍照. OBJECT参数说明: 注:文件的临时路径,在小程序本次启动期间可以正常使用,如需持久保存,需在主动调用 wx.saveFile,在小程序下次启动时才能访问得到. 示例代码: wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'],

微信小程序 require机制详解及实例代码_JavaScript

微信小程序 require机制详解 一, JS模块加载:一次性加载全部JS, 但并不一定立即执行. 先提一提微信小程序架构: 类浏览器 -> HTTP本地服务 -> 云端服务 微信小程序运行的架构,基本上是浏览器 -> HTTP本地服务 -> 云端服务, HTTP本地服务用来读取本地文件或者代理云端的文件资源.读取项目中JS文件, 是由HTTP本地服务取本地存储的脚本文件. 似乎比较简单,一个HTML 引用所有JS文件 既然采用了这种架构,那微信小程序就类似浏览器那样,借助一个HT

微信小程序 scroll-view组件实现列表页实例代码_JavaScript

scroll-view组件介绍 scroll-view是微信小程序提供的可滚动视图组件,其主要作用是可以用来做手机端经常会看到的上拉加载下拉刷新列表页!下面就以<摇出微笑>为例来讲解一下这个组件的使用吧! 为app导入新page页面 首先需要为我们的小程序导入新的page页面,项目根目录打开app.json这个项目配置文件在里面的pages数组添加"pages/allJoke/allJoke"然后设置底部导航在"tabBar"的列表项("lis

微信小程序 五星评分(包括半颗星评分)实例代码_JavaScript

微信小程序 五星评分 一位同学说要写五星评分.要有半颗星的评分. 于是我做了个玩具.有空了做模块化,这代码看不下去了. 代码: 1.index.wxml <!--index.wxml--> <block wx:for="{{stars}}"> <image class="star-image" style="left: {{item*150}}rpx" src="{{key > item ?(key-

微信小程序 滚动选择器(时间日期)详解及实例代码

微信小程序  滚动选择器(时间日期)详解 微信小程序自己封装了很多控件,用起来确实很方便,如果这是Android里面,还需要自己去定义,不废话,效果图: 一起来看看怎么实现的呢?看完你应该就该说,尼玛,这就行啦-. 这个效果呢,要用到picker组件,动画从底部弹起的滚动选择器,现支持三种选择器,通过mode来区分,分别是普通选择器,时间选择器,日期选择器,默认是普通选择器. 看下相应的属性: 具体的来看看代码,布局: <view class="section" > <

你能用微信小程序打开小程序了【附开发方法】

6月21日晚间,微信小程序再次迎来升级:小程序可以打开小程序了,同一个公众号下关联的10个同主体小程序和3个非同主体小程序之间,可以调用接口直接相互跳转.微信客户端6.5.9及以上版本支持.另外门店小程序的门店页支持添加视频:为了方便宣传门店形象,门店小程序的门店页支持可添加视频.(添加视频方式有两种:1.上传视频至公众号素材库添加.2.输入视频链接或含视频的图文消息链接添加.)门店小程序支持接口管理,提供创建商家,新增.查询.修改和删除门店等接口,同时支持第三方平台授权调用,方便批量管理门店.