前一阵子开发微信小程序功能,需要用到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;