1. 小程序网络请求基础与wx.request核心功能
微信小程序中的网络请求能力是连接前后端数据的关键桥梁,而wx.request作为基础API,其重要性不言而喻。这个API本质上是对浏览器原生XMLHttpRequest的封装,但针对小程序运行环境做了深度优化。与常规网页开发不同,小程序网络请求必须遵循微信的安全规范,包括强制HTTPS、域名白名单等限制。
wx.request的基础调用形式如下:
javascript复制wx.request({
url: 'https://api.example.com/data',
method: 'GET',
data: { id: 123 },
success(res) {
console.log(res.data)
},
fail(err) {
console.error(err)
}
})
这个看似简单的API背后,微信团队其实做了大量工作:
- 自动处理了iOS/Android平台的网络差异
- 内置了请求超时管理(默认60秒)
- 实现了请求队列的优先级控制
- 支持HTTP/2等现代协议
重要提示:从2022年起,微信强制要求所有小程序后端接口必须使用HTTPS,且域名必须在小程序后台配置。开发阶段可在开发者工具中勾选"不校验合法域名"选项,但上线前必须完成配置。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 实战中的高级配置与性能优化
2.1 请求超时与重试机制
实际业务中,简单的success/fail回调往往不能满足需求。我们通常需要配置更精细的超时控制和自动重试:
javascript复制const retryRequest = (options, retries = 3) => {
return new Promise((resolve, reject) => {
const attempt = (n) => {
wx.request({
...options,
timeout: 10000, // 10秒超时
success: resolve,
fail: (err) => {
if (n > 0) {
console.log(`第${retries - n + 1}次重试...`)
attempt(n - 1)
} else {
reject(err)
}
}
})
}
attempt(retries)
})
}
2.2 并发请求管理
小程序对并发请求有限制(目前是10个),在复杂场景下需要特别管理:
javascript复制// 使用Promise.all控制并发
const fetchMultiData = async (urls) => {
try {
const requests = urls.map(url =>
new Promise((resolve) => {
wx.request({
url,
success: resolve
})
})
)
return await Promise.all(requests)
} catch (e) {
console.error('批量请求失败', e)
throw e
}
}
2.3 缓存策略实现
合理利用缓存可以显著提升用户体验:
javascript复制const cache = new Map()
const smartRequest = (options) => {
const cacheKey = JSON.stringify(options)
if (cache.has(cacheKey)) {
const { expire, data } = cache.get(cacheKey)
if (Date.now() < expire) {
return Promise.resolve(data)
}
}
return new Promise((resolve, reject) => {
wx.request({
...options,
success: (res) => {
cache.set(cacheKey, {
data: res.data,
expire: Date.now() + 300000 // 5分钟缓存
})
resolve(res.data)
},
fail: reject
})
})
}
3. 安全防护与异常处理实战
3.1 防CSRF攻击方案
小程序环境虽然相对安全,但仍需防范常见网络攻击:
javascript复制// 请求拦截器示例
const secureRequest = (options) => {
const timestamp = Date.now()
const nonceStr = Math.random().toString(36).substr(2)
const signature = sha256(`${timestamp}${nonceStr}${appSecret}`)
return wx.request({
...options,
header: {
...options.header,
'X-Timestamp': timestamp,
'X-Nonce': nonceStr,
'X-Signature': signature
}
})
}
3.2 全链路错误监控
完善的错误处理应该包含:
- 网络层错误(超时、断开)
- HTTP状态码错误(4xx/5xx)
- 业务逻辑错误(后端返回的特定错误码)
- 数据格式错误(JSON解析异常)
javascript复制wx.request({
url: 'https://api.example.com/data',
success(res) {
if (res.statusCode !== 200) {
reportError('HTTP_ERROR', res.statusCode)
return
}
try {
const data = JSON.parse(res.data)
if (data.code !== 0) {
handleBusinessError(data.code)
} else {
processData(data)
}
} catch (e) {
reportError('PARSE_ERROR', e)
}
},
fail(err) {
reportError('NETWORK_ERROR', err)
}
})
4. 企业级项目中的最佳实践
4.1 请求工厂模式
大型项目中推荐使用工厂模式统一管理请求:
javascript复制class RequestClient {
constructor(baseURL) {
this.baseURL = baseURL
this.interceptors = {
request: [],
response: []
}
}
request(options) {
// 请求拦截
let config = { ...options, url: this.baseURL + options.url }
this.interceptors.request.forEach(fn => {
config = fn(config) || config
})
return new Promise((resolve, reject) => {
wx.request({
...config,
success: (res) => {
// 响应拦截
let response = res
this.interceptors.response.forEach(fn => {
response = fn(response) || response
})
resolve(response)
},
fail: reject
})
})
}
addInterceptor(type, fn) {
this.interceptors[type].push(fn)
}
}
// 使用示例
const api = new RequestClient('https://api.example.com')
api.addInterceptor('request', config => {
config.header = config.header || {}
config.header['Authorization'] = getToken()
return config
})
4.2 类型安全的请求处理
结合TypeScript可以获得更好的开发体验:
typescript复制interface ApiResponse<T> {
code: number
message: string
data: T
}
async function typedRequest<T>(options: WechatMiniprogram.RequestOption): Promise<T> {
return new Promise((resolve, reject) => {
wx.request({
...options,
success: (res) => {
if (res.statusCode === 200) {
const data = res.data as ApiResponse<T>
if (data.code === 0) {
resolve(data.data)
} else {
reject(new Error(data.message))
}
} else {
reject(new Error(`HTTP ${res.statusCode}`))
}
},
fail: reject
})
})
}
// 使用示例
interface UserInfo {
name: string
age: number
}
const user = await typedRequest<UserInfo>({
url: '/user/123'
})
4.3 性能监控与优化
通过封装可以实现自动性能上报:
javascript复制const trackedRequest = (options) => {
const startTime = Date.now()
const traceId = generateTraceId()
return new Promise((resolve, reject) => {
wx.request({
...options,
header: {
...options.header,
'X-Trace-Id': traceId
},
success: (res) => {
reportPerformance({
traceId,
duration: Date.now() - startTime,
status: 'success',
size: JSON.stringify(res.data).length
})
resolve(res)
},
fail: (err) => {
reportPerformance({
traceId,
duration: Date.now() - startTime,
status: 'fail',
error: err.errMsg
})
reject(err)
}
})
})
}
在实际项目中,我们还会遇到各种特殊场景的处理需求,比如:
- 大文件分片上传
- WebSocket与请求的协同
- 离线模式下的请求队列管理
- 请求优先级调度
- 请求取消与超时竞速
每个场景都需要根据具体业务需求进行针对性设计。比如大文件上传就需要特殊处理:
javascript复制const uploadFile = (filePath, onProgress) => {
return new Promise((resolve, reject) => {
const uploadTask = wx.uploadFile({
url: 'https://api.example.com/upload',
filePath,
name: 'file',
success: resolve,
fail: reject
})
uploadTask.onProgressUpdate((res) => {
onProgress && onProgress(res.progress)
})
})
}
这些年来,我在多个小程序项目中积累的最重要经验是:网络请求不是独立存在的,它需要与小程序的其他能力(如本地存储、页面生命周期、用户授权等)协同工作,才能构建出真正健壮的应用。比如在用户token过期时自动刷新、在网络恢复后重试失败的请求等,这些细节往往决定了用户体验的好坏。
