在小程序中发送网络请求,需要使用微信提供的API,提供了5种:
- 普通 HTTPS 请求(
wx.request
) - 上传文件(
wx.uploadFile
) - 下载文件(
wx.downloadFile
) - WebSocket 通信(
wx.connectSocket
) - UDP 通信(
wx.createUDPSocket
)
一般项目中使用频率最高的是 wx.request
和 wx.uploadFile
需要注意的是,小程序只可以跟指定的域名进行网络通信,需要事先设置通讯域名(服务器域名请在 「小程序后台-开发-开发设置-服务器域名」 中进行配置)。
可以查看 配置流程 了解一下具体注意项。
#1 HTTPS 请求
wx.request(options)
可以传入一个 options
对象,具体可以配置哪些参数可以查看 发起请求 - 参数 ,我就不一一例出来了。
简单的上一个登陆请求示例:
wx.request({
url: 'https://example.weixin.qq.com/login', // 接口地址
data: { // 请求参数
uid: 'admin',
pwd: '123456'
},
header: { // 请求头
'content-type': 'application/json' // 默认json,为了举例我还是写上来了
},
method:'POST', // 请求类型
success (res) {
// 接口调用成功的回调函数
},
fail (err) {
// 接口调用失败的回调函数
}
})
需要注意的是:
- 不支持以 Promise 风格 调用。
Promise 风格 是基础库版本 2.10.2 起开始支持的新调用方式,旧版本只能使用callback
的形式来处理 - 最终发送给服务器的数据是 String 类型,如果传入的
data
不是String
类型,会被转换成String
,可以查看 data 参数说明
不过一般我会自己把请求函数 Promisify,如下
// request.js
export function request ({ url, method, data, contentType = {} }) {
const { requestUrl } = getApp().globalData // 在 app.js 设置的全局变量
const apiUrl = requestUrl + url // 拼接完整请求地址
const token = wx.getStorageSync("token")
const header = Object.assign({ "content-type": "application/json", "X-Access-Token": token }, contentType)
console.info("请求接口: ", apiUrl);
console.info("请求头部: ", header)
console.info("请求参数: ", data)
return new Promise((resolve, reject) => {
wx.request({
url: apiUrl,
data: data,
method: method,
header: header,
success (res) {
console.info(`[${apiUrl}]请求返回值:`);
console.table(res.data)
const { success, result, message } = res.data
if(success) {
resolve(res.data)
} else {
reject(res.data)
console.warn("ERROR_URL:", url)
return onErr(res.data) // 异常处理
}
},
fail (err) {
reject(err)
Toast({ title: "服务器异常,请重试!" }) // 封装的wx.showToast()
console.warn("----------请求异常-----------")
console.warn(err)
}
})
})
}
然后再封装一下不同的请求方法,在使用的时候按需引入就好了
// manage.js
import { request } from './request'
export const FORM_DATA = {"content-type": "application/x-www-form-urlencoded;charset=UTF-8"}
// post
export function postAction (url, parameter, contentType = {}) {
return request({
url: url,
method: 'POST',
data: parameter,
contentType:contentType,
})
}
// http method= {POST | PUT}
export function httpAction (url, parameter = {}, method, contentType = {}) {
return request({
url: url,
method: method,
data: parameter,
contentType:contentType,
})
}
// put
export function putAction (url, parameter = {}, contentType = FORM_DATA) {
return request({
url: url,
method: 'PUT',
data: parameter,
contentType:contentType,
})
}
// get
export function getAction (url, parameter = {}, contentType = {}) {
return request({
url: url,
method: 'GET',
data: parameter,
contentType:contentType,
})
}
// delete
export function deleteAction (url, parameter = {}, contentType = {}) {
return request({
url: url,
method: 'DELETE',
data: parameter,
contentType:contentType,
})
}
是不是有一股子 Ant Design Vue Pro 的味道 😂😂😂
#2 上传文件
wx.uploadFile(options)
,可以传入一个 options
对象,参数配置文档
注意:客户端发起一个
HTTPS POST
请求,其中content-type
为multipart/form-data
。
示例代码:
wx.chooseImage({
success (res) {
const tempFilePaths = res.tempFilePaths // 获取的文件临时路径
wx.uploadFile({
url: 'https://example.weixin.qq.com/upload', // 请求的网络接口
filePath: tempFilePaths[0], // 文件路径
name: 'file', // 文件key,服务端可以通过这个 key 获取文件二进制内容
formData: { // 额外的 formData 可以不传
'user': 'test'
},
success (result){
// 接口调用成功的回调函数
},
fail (error){
// 接口调用失败的回调函数
}
})
}
})
同样也会封装成 Promise
// request.js
export function uploadFile ({ url, data }) {
const { requestUrl } = getApp().globalData // 在 app.js 设置的全局变量
const apiUrl = requestUrl + url
const token = wx.getStorageSync("token")
const header = { "X-Access-Token": token }
console.info("请求接口: ", apiUrl);
console.info("请求头部: ", header)
console.info("文件地址: ", data)
return new Promise((resolve, reject) => {
wx.uploadFile({
url: apiUrl,
filePath: data.filePath,
name: 'file',
header: header,
success: (res) => {
console.info(`[${apiUrl}]请求返回值:`);
console.table(res.data)
const { data, statusCode } = res
if (statusCode !== 200){
Toast({ title: "上传失败" })
reject(res.data)
return
}
// 这里需要注意是否返回的是JSON格式的 data
const d = JSON.parse(data)
const { success, result, message } = data
if (success) {
resolve(d)
} else {
reject(res.data)
console.warn("ERROR_URL:", url)
return onErr(d) // 异常处理
}
},
fail (err) {
reject(err)
Toast({ title: "服务器异常,请重试!" })
console.warn("-----------上传失败-----------");
console.warn(err);
}
})
})
}
#3 下载文件
wx.downloadFile(options)
,同样也可以传入一个 options
对象,配置文档 DownloadTask | 微信开放文档
- 发起一个
HTTPS GET
请求 - 返回文件的本地临时路径 (本地路径)
- 单次下载允许的最大文件为
200MB
注意:请在服务端响应的
header
中指定合理的Content-Type
字段,以保证客户端正确处理文件类型。
示例代码
wx.downloadFile({
url: 'https://example.com/audio/123', // 仅为示例,并非真实的资源
success (res) {
// 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
if (res.statusCode === 200) {
wx.playVoice({
filePath: res.tempFilePath
})
}
}
})
暂时还没有使用的场景,就暂时不描述了,WebSocket 也是还没有在小程序业务上使用过,就不细说了,简单的用文档中的示例
#4 WebSocket 通信
首先需要使用 wx.connectSocket(options)
创建一个 WebSocket 连接。具体文档 SocketTask | 微信开放文档
然后就和正常使用 WebSocket 一样了:
方法
wx.sendSocketMessage(Object object)
通过 WebSocket 连接发送数据。wx.closeSocket(Object object)
关闭 WebSocket 连接
事件
- 全局事件
wx.onSocketOpen(callback)
监听 WebSocket 连接打开事件wx.onSocketMessage(callback)
监听 WebSocket 接受到服务器的消息事件wx.onSocketError(callback)
监听 WebSocket 错误事件wx.onSocketClose(callback)
监听 WebSocket 连接关闭事件
- 当前Socket事件
- 通过
wx.connectSocket()
接口创建返回赋值给变量SocketTask
SocketTask.onSocketOpen(callback)
监听 WebSocket 连接打开事件SocketTask.onSocketMessage(callback)
监听 WebSocket 接受到服务器的消息事件SocketTask.onSocketError(callback)
监听 WebSocket 错误事件SocketTask.onSocketClose(callback)
监听 WebSocket 连接关闭事件
- 通过
#5 UDP 通信
使用 wx.createUDPSocket()
创建一个 UDP Socket 实例,之后就可以和 WebSocket
通信类似的方式使用 UDPSocket
API来通信了,具体文档 UDPSocket | 微信开放文档
方法
UDPSocket.bind(number port)
绑定一个可用端口号UDPSocket.send()
向指定的 IP 和 port 发送消息UDPSocket.connect(Object object)
预先连接到指定的 IP 和 port,需要配合 write 方法一起使用UDPSocket.write()
用法与 send 方法相同,如果没有预先调用 connect 则与 send 无差异UDPSocket.close()
关闭 UDP Socket 实例,相当于销毁
事件
UDPSocket.onClose(callback)
监听关闭事件UDPSocket.offClose(callback)
取消监听关闭事件UDPSocket.onError(callback)
监听错误事件UDPSocket.offError(callback)
取消监听错误事件UDPSocket.onListening(callback)
监听开始监听数据包消息的事件UDPSocket.offListening(callback)
取消监听开始监听数据包消息的事件UDPSocket.onMessage(callback)
监听收到消息的事件UDPSocket.offMessage(callback)
取消监听收到消息的事件
错误码之类的直接看 文档 吧。
这个API应该是和我无缘了,物联网和直播之类的场景我应该是很难遇到的。
其它
📌 配置网络请求超时时间
如果需要配置超时时间则需要去 app.json
中配置 networkTimeout
,
默认 60000
(单位:毫秒),最大超时时间也是 60000
。
可以为4个网络请求单独配置超时时间,具体查看 👉 配置文档
// app.json
{
// 其他配置项....
"networkTimeout": {
"request": 10000, // wx.request 的超时时间
"uploadFile": 10000 // wx.uploadFile 的超时时间
}
}