前一阵子开发微信小程序功能,需要用到wx.request请求服务器接口,接口需要传递form-data参数,但是按官方文档提供的wx.request请求总是不成功。

找了些资料都说wx.request不支持,得用wx.uploadFile来实现。其实是可以的,只是没有找到正确的打开方式而已。

经过参考一些资料以及多次试验,最终解决了这个问题,特意整理一下。整个调试及解决问题的过程如下:

1、确认服务器接口是否正常。

使用postman访问服务器接口,按要求传递参数,结果返回正常,说明服务器接口没有问题。

2、通过多次调试,最终问题确定在content-type和data范围内

网上有些资料说wx.request中content-type无法使用multipart/form-data,但是尝试了application/json、application/x-www-form-urlencoded等多种方式都不行。

然而在postman中使用multipart/form-data是成功的,所以判定content-type使用multipart/form-data是正确的,问题可能是data数据的格式造成的。

3、尝试修改data数据格式,问题解决

首先,将data格式传递json对象,结果失败。

其次,将data格式传递json字符串,结果仍然失败。

最后,参考了网上一个例子,将data格式做如下拼接后问题解决:

wx.request({
    url: "http://接口地址",
    method: 'POST',
    data: '\r\n--XXX' +
        '\r\nContent-Disposition: form-data; name="参数名称"' +
        '\r\n' +
        '\r\n' + JSON.stringify(postData) +
        '\r\n--XXX',
    header: {
        'content-type': 'multipart/form-data; boundary=XXX'
    },
    success: function(res) {
        //参数值为res.data,直接将返回的数据传入
        doSuccess(res.data);
    },
    fail: function(res) {
        doFail(res);
    }
})

其中,【接口地址】是服务器接口的地址,【参数名称】是接口提交需要的参数,postData即为提交的数据,如果是多个参数,可以继续添加字符串参数部分:

'\r\nContent-Disposition: form-data; name="参数名称2"' +
'\r\n' +
'\r\n' + JSON.stringify(postData2) +
'\r\n--XXX',

4、参考资料使用wx.request发送multipart/form-data请求的方法 | 微信开放社区 (qq.com)

5、附一个自己整理的request类

var app = getApp();
var domain = "配置接口统一域名地址";

/**
 * POST请求,返回数据不做解析
 * URL:接口
 * postData:参数,json类型
 * doSuccess:成功的回调函数
 * doFail:失败的回调函数
 */
function requestPost(url, postData, doSuccess, doFail) {
  wx.request({
    //项目的真正接口,通过字符串拼接方式实现
    url: domain + url,
    header: {
      "content-type": "application/json;charset=UTF-8"
    },
    data: postData,
    method: 'POST',
    success: function (res) {
      //参数值为res.data,直接将返回的数据传入
      doSuccess(res.data);
    },
    fail: function () {
      doFail();
    },
  })
}
/**
 * POST请求,返回数据解析json对象
 * URL:接口
 * postData:参数,json类型
 * doSuccess:成功的回调函数
 * doFail:失败的回调函数
 */
function requestPost2(url, postData, doSuccess, doFail) {
  wx.request({
    url: domain + url,
    method: 'POST',
    data: '\r\n--XXX' +
      '\r\nContent-Disposition: form-data; name="message"' +
      '\r\n' +
      '\r\n' + JSON.stringify(postData) +
      '\r\n--XXX',
    header: {
      'content-type': 'multipart/form-data; boundary=XXX'
    },
    success: function (res) {
      //参数值为res.data,直接将返回的数据传入
      // console.log(res);
      var jsonStr = res.data;
      if (typeof jsonStr != 'object' && jsonStr != "empty") {
        jsonStr = jsonStr.replace(/\ufeff/g, ""); //重点
        var jobj = JSON.parse(jsonStr); // 转对象
        doSuccess(jobj);
      }
      else
        doSuccess(res.data);
    },
    fail: function (res) {
      doFail(res);
    }
  })
}

//GET请求,不需传参,直接URL调用,
function requestGet(url, doSuccess, doFail) {
  wx.request({
    url: host + url,
    header: {
      "content-type": "application/json;charset=UTF-8"
    },
    method: 'GET',
    success: function (res) {
      doSuccess(res.data);
    },
    fail: function () {
      doFail();
    },
  })
}

/**
 * module.exports用来导出代码
 * js文件中通过var request = require("../util/request.js")  加载
 * 在引入引入文件的时候"  "里面的内容通过../../../这种类型,小程序的编译器会自动提示,因为你可能
 * 项目目录不止一级,不同的js文件对应的工具类的位置不一样
 */
module.exports.requestPost = requestPost;
module.exports.requestPost2 = requestPost2;
module.exports.requestGet = requestGet;