发送网络请求
uni-app 中发送网络请求的常识
uni-app
的网络请求 API 名为uni.request
,它在所有支持uni-app
的平台上都可用,包括 H5、小程序(微信/百度/字节跳动等)、App 等。- 小程序平台通常有域名白名单限制,需要在小程序后台配置可以请求的域名;而在 App/H5 场景下则不需要此步骤(H5 会涉及跨域配置,App 端没有跨域限制)。
- 由于小程序和普通浏览器环境存在差异,小程序中的请求并不走浏览器
XMLHttpRequest
(也就没有传统跨域限制的概念),因此可以直接请求后端接口。
# 一、使用 uni.request(OBJECT) 进行请求
uni.request
是最基本的网络请求接口,支持 Promise 回调形式,也可以使用传统的回调 success
/ fail
/ complete
方式。
# 1.1 基本用法与参数说明
官方文档地址:uni.request(OBJECT) | uni-app官网 (opens new window)
uni.request({
url: 'http://example.com/api/test', // 开发者服务器接口地址
method: 'GET', // 请求方法,默认为GET
data: { // 请求数据
name: '张三',
age: 18
},
header: { // 请求头
'content-type': 'application/json'
},
success: (res) => {
console.log(res.data); // 服务器返回的数据
},
fail: (err) => {
console.error(err); // 请求失败的错误信息
},
complete: () => {
console.log('请求完成'); // 成功或失败都会执行
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
OBJECT 参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
url | String | 是 | -- | 开发者服务器接口地址 | |
data | Object/String/ArrayBuffer | 否 | -- | 请求的参数 | App 3.3.7 以下不支持 ArrayBuffer |
header | Object | 否 | -- | 设置请求的 header | App、H5 端会自动带上 cookie,H5 不可手动修改 |
method | String | 否 | GET | 请求方法,有效值详见method 有效值 (opens new window) | |
timeout | Number | 否 | 60000 | 超时时间,单位 ms | H5(HBuilderX 2.9.9+)、App(HBuilderX 2.9.9+)、微信小程序2.10.0+、支付宝小程序等 |
dataType | String | 否 | json | 如果设为 json ,会尝试对返回的数据做一次 JSON.parse | |
responseType | String | 否 | text | 设置响应的数据类型,合法值:text 、arraybuffer | 支付宝小程序不支持 |
sslVerify | Boolean | 否 | true | 验证 ssl 证书 | 仅 App-Android 支持(HBuilderX 2.3.3+),不支持离线打包 |
withCredentials | Boolean | 否 | false | 跨域请求时是否携带凭证(cookies) | 仅H5支持(HBuilderX 2.6.15+) |
firstIpv4 | Boolean | 否 | false | DNS解析时优先使用ipv4 | 仅 App-Android 支持 (HBuilderX 2.8.0+) |
success | Function | 否 | -- | 收到开发者服务器成功返回的回调函数 | |
fail | Function | 否 | -- | 接口调用失败的回调函数 | |
complete | Function | 否 | -- | 接口调用结束的回调函数(成功、失败都会执行) | |
... | - | - | - | 其他详细参数参见官网描述 |
若你的接口需要登录态或鉴权信息,可在
header
中自定义Authorization
头或将 token 附在data
里,视后端接口需求而定。
# 1.2 method 有效值
method
必须为大写,且不同平台支持的请求方法不完全相同。下表供参考:
method | App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节跳动小程序、飞书小程序 | 快手小程序 | 京东小程序 |
---|---|---|---|---|---|---|---|---|
GET | √ | √ | √ | √ | √ | √ | √ | √ |
POST | √ | √ | √ | √ | √ | √ | √ | √ |
PUT | √ | √ | √ | x | √ | √ | x | x |
DELETE | √ | √ | √ | x | √ | x | x | x |
CONNECT | x | √ | √ | x | x | x | x | x |
HEAD | √ | √ | √ | x | √ | x | x | x |
OPTIONS | √ | √ | √ | x | √ | x | x | x |
TRACE | x | √ | √ | x | x | x | x | x |
一般业务中,常见的方法是
GET
、POST
,有时会用到PUT
、DELETE
,看后端接口约定。
# 1.3 success 回调与返回参数说明
在 success
回调里,主要会返回以下几个字段:
参数 | 类型 | 说明 |
---|---|---|
data | Object/String/ArrayBuffer | 开发者服务器返回的数据 |
statusCode | Number | 开发者服务器返回的 HTTP 状态码 |
header | Object | 开发者服务器返回的 HTTP Response Header |
cookies | Array<string> | 服务器返回的 cookies,格式为字符串数组 |
data 说明
- 如果
method
为GET
,默认会把data
转为 QueryString 拼接到 URL 上。 - 如果
method
为POST
且content-type
为application/json
,请求数据会进行 JSON 序列化后发送。 - 如果
method
为POST
且content-type
为application/x-www-form-urlencoded
,则会将data
转为 QueryString 形式发送。
# 1.4 发起测试请求示例
下面是一个简单的 Spring Boot 后端接口,用于测试:
该接口返回成功。我们在 uni-app
中写一个页面调用它:
执行后可以看到返回的数据:
ok,搞定
因为在小程序平台并不存在浏览器层面的跨域限制,直接调用后端接口即可获得结果。若在 H5 平台访问,就需要后端配合开启 CORS 或反向代理。
# 1.5 小程序调试提示
如果在微信开发者工具中请求失败,也可能是因为还没在微信小程序后台配置域名白名单,或者需要在开发者工具设置里勾选“不校验合法域名”:
这种操作仅供开发测试使用,正式上线需在小程序管理平台配置合法域名。
# 二、二次封装请求对象
# 2.1 为什么要进行二次封装
- 如果每次都写
uni.request({ url: 'http://xx:8000/xxx', ... })
,当地址或端口号变动时,所有写死的请求都需手动修改,容易出错且耗时。 - 二次封装可以统一管理项目中的请求逻辑,如公共请求头、token、错误码处理等。
# 2.2 request.js 示例
以下是一个最简易的二次封装示例,将公共的 BASE_URL
、错误处理、返回结构等集中管理。
// request.js
// 定义基础 URL
const BASE_URL = 'http://localhost:8000';
export const myRequest = (options) => {
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + options.url, // 拼接请求地址
method: options.method || 'GET', // 请求方法,默认为 GET
data: options.data || {}, // 请求参数
success: (res) => {
// 根据业务需求判断响应结构
// 假设约定 res.data 里面包含 code==1 表示成功
if (res.data.code !== 1) {
// 数据获取失败时弹出提示
uni.showToast({
title: '获取数据失败',
icon: 'none'
});
return;
}
// 成功时返回数据
resolve(res);
},
fail: (err) => {
// 请求失败弹出提示
uni.showToast({
title: '请求接口失败',
icon: 'none'
});
// 返回错误信息
reject(err);
}
});
});
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
你可在封装中加更多逻辑,比如针对
401
未登录时自动跳转登录页,或统一处理异常信息等。
# 2.3 引入封装请求到项目中
在 main.js
或其它合适的地方,将 myRequest
挂载到 Vue.prototype
(或者使用更现代的方式——直接在各个页面的脚本中 import
引用)。
这样,在页面脚本中就可以通过 this.$myRequest
或直接 import { myRequest } from '@/utils/request.js';
来进行请求。
# 2.4 在页面中使用示例
这里演示请求另一个接口,以验证二次封装后的调用流程:
- 后端接口:和之前一样是一个简单的 Spring Boot / Node / PHP 接口,返回一些 JSON 数据。
- 前端页面:在 Vue 脚本里使用二次封装后的方法。
在页面中:
<template>
<view>
<text v-if="user">{{ user.name }}-{{ user.age }}</text>
<text v-else>数据加载中...</text>
</view>
</template>
<script>
import { myRequest } from '@/utils/request.js'; // 导入二次封装的请求方法
export default {
data() {
return {
user: null
};
},
onLoad() {
this.loadUserData();
},
methods: {
async loadUserData() {
try {
const res = await myRequest({
url: '/user/info', // 接口相对地址
method: 'GET'
});
// res.data.data 才是我们需要的真实用户数据
this.user = res.data.data;
} catch (err) {
console.error('请求出错:', err);
}
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
这样,我们就完成了对请求的二次封装与实际使用。
# 2.5 常见问题和思考
需要做全局错误处理吗?
- 如果在接口返回
code != 1
时所有页面都要执行同样的操作,可以放在二次封装中集中处理。 - 如果各页面期望不同的处理逻辑,则可以只做基础提示,把详细处理放到页面的
catch
或then
中。
- 如果在接口返回
拦截器功能
- 一些开发者习惯在封装时实现类似 Axios 的“请求拦截器/响应拦截器”,对
uni.request
进行“多次封装”。官方暂未提供类似自定义拦截器的API,但可在uni.request
之前/之后手动实现逻辑分层。
- 一些开发者习惯在封装时实现类似 Axios 的“请求拦截器/响应拦截器”,对
Token 或其他鉴权信息
可以在封装时将 token 注入 header中,例如:
header: { Authorization: 'Bearer ' + uni.getStorageSync('token') || '' }
1
2
3针对过期或无效 token,可统一在
fail
或res.data.code
里判断并做跳转登录等操作。
跨域与白名单
- H5 平台:需要后端 CORS 或用前端代理解决跨域。
- 微信/支付宝/百度/字节跳动小程序等:需在小程序控制台配置合法请求域名或在开发者工具中临时关闭校验。