网络请求(uni.request)
uni-app 是一个使用 Vue.js 开发跨平台应用的框架,支持编译到多个平台。uni.request
是 uni-app 提供的网络请求 API,用于发起 HTTP 请求。它的用法类似于微信小程序的 wx.request
,但在 uni-app 中可以跨平台使用。
uni.request 的基本用法
uni.request
是一个异步方法,用于发送 HTTP 请求。它的基本语法如下:
uni.request({
url: 'https://example.com/api',
method: 'GET',
data: {
key1: 'value1',
key2: 'value2'
},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
console.log(res.data);
},
fail: (err) => {
console.error(err);
},
complete: () => {
console.log('请求完成');
}
});
参数说明
url
:请求的接口地址,必需。method
:请求方法,如GET
、POST
、PUT
、DELETE
等,默认为GET
。data
:请求的参数,可以是对象或字符串。header
:请求头,可以设置Content-Type
等。success
:请求成功的回调函数,返回响应数据。fail
:请求失败的回调函数,返回错误信息。complete
:请求完成的回调函数(无论成功或失败都会执行)。
发送 GET 请求
GET 请求通常用于获取数据。以下是一个获取用户信息的示例:
uni.request({
url: 'https://api.example.com/users',
method: 'GET',
data: {
userId: 123
},
success: (res) => {
console.log('用户信息:', res.data);
},
fail: (err) => {
console.error('请求失败:', err);
}
});
发送 POST 请求
POST 请求通常用于提交数据。以下是一个提交表单的示例:
uni.request({
url: 'https://api.example.com/submit',
method: 'POST',
data: {
name: '张三',
age: 25
},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
console.log('提交成功:', res.data);
},
fail: (err) => {
console.error('提交失败:', err);
}
});
设置请求头
请求头可以通过 header
参数设置。例如,设置 Authorization
用于身份验证:
uni.request({
url: 'https://api.example.com/protected',
method: 'GET',
header: {
'Authorization': 'Bearer your_token_here'
},
success: (res) => {
console.log('受保护的数据:', res.data);
}
});
处理响应数据
success
回调函数的参数 res
包含以下字段:
data
:服务器返回的数据。statusCode
:HTTP 状态码。header
:响应头。
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('状态码:', res.statusCode);
console.log('响应头:', res.header);
console.log('数据:', res.data);
}
});
错误处理
通过 fail
回调可以捕获请求失败的情况:
uni.request({
url: 'https://api.example.com/error',
fail: (err) => {
console.error('请求出错:', err);
// 可以在这里显示错误提示
uni.showToast({
title: '网络请求失败',
icon: 'none'
});
}
});
使用 async/await
uni.request
也支持 Promise 风格调用,可以与 async/await
结合使用:
async function fetchData() {
try {
const res = await uni.request({
url: 'https://api.example.com/data',
method: 'GET'
});
console.log('数据:', res[1].data); // 注意:返回的是一个数组 [err, res]
} catch (err) {
console.error('请求失败:', err);
}
}
fetchData();
请求超时设置
可以通过 timeout
参数设置请求超时时间(单位:毫秒):
uni.request({
url: 'https://api.example.com/slow',
timeout: 5000, // 5秒超时
success: (res) => {
console.log('请求成功:', res.data);
},
fail: (err) => {
console.error('请求超时或失败:', err);
}
});
文件上传
uni.uploadFile
用于文件上传,但也可以通过 uni.request
实现文件上传(需手动处理 FormData):
uni.chooseImage({
success: (chooseRes) => {
const tempFilePaths = chooseRes.tempFilePaths;
uni.request({
url: 'https://api.example.com/upload',
method: 'POST',
filePath: tempFilePaths[0],
name: 'file',
formData: {
userId: '123'
},
success: (uploadRes) => {
console.log('上传成功:', uploadRes.data);
}
});
}
});
拦截器
uni-app 本身不提供拦截器功能,但可以通过封装 uni.request
实现类似功能:
const request = (options) => {
// 添加全局请求头
const defaultHeader = {
'X-Requested-With': 'XMLHttpRequest'
};
options.header = Object.assign(defaultHeader, options.header || {});
// 添加 token
const token = uni.getStorageSync('token');
if (token) {
options.header.Authorization = `Bearer ${token}`;
}
return new Promise((resolve, reject) => {
uni.request({
...options,
success: (res) => {
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res.data);
} else {
reject(res);
}
},
fail: (err) => {
reject(err);
}
});
});
};
// 使用封装后的 request
request({
url: 'https://api.example.com/data',
method: 'GET'
}).then(data => {
console.log(data);
}).catch(err => {
console.error(err);
});
跨域问题
在开发环境中,可能会遇到跨域问题。可以通过以下方式解决:
- 在
manifest.json
中配置代理:
{
"h5": {
"devServer": {
"proxy": {
"/api": {
"target": "https://api.example.com",
"changeOrigin": true,
"pathRewrite": {
"^/api": ""
}
}
}
}
}
}
然后在代码中请求 /api
路径即可。
- 后端设置 CORS 头。
实际应用示例
以下是一个完整的用户登录示例:
// 登录方法
async function login(username, password) {
try {
const res = await uni.request({
url: 'https://api.example.com/login',
method: 'POST',
data: {
username,
password
},
header: {
'Content-Type': 'application/json'
}
});
const data = res[1].data;
if (data.token) {
uni.setStorageSync('token', data.token);
uni.showToast({
title: '登录成功',
icon: 'success'
});
return true;
} else {
throw new Error(data.message || '登录失败');
}
} catch (err) {
uni.showToast({
title: err.message,
icon: 'none'
});
return false;
}
}
// 在页面中调用
login('admin', '123456').then(success => {
if (success) {
uni.navigateTo({
url: '/pages/home/index'
});
}
});
性能优化建议
- 合理设置缓存:对于不常变动的数据,可以使用
uni.setStorage
缓存响应结果。 - 合并请求:减少请求次数,多个接口可以合并为一个。
- 取消请求:长时间未响应的请求应该取消,避免资源浪费。
- 压缩数据:与后端协商使用 gzip 压缩响应数据。
// 缓存示例
async function getCachedData() {
const cacheKey = 'cached_data';
const cachedData = uni.getStorageSync(cacheKey);
if (cachedData) {
return cachedData;
}
const res = await uni.request({
url: 'https://api.example.com/data'
});
const data = res[1].data;
uni.setStorageSync(cacheKey, data);
return data;
}
注意事项
- 在微信小程序中,
uni.request
的url
必须配置在request
合法域名中。 - 在 H5 端,跨域问题需要后端配合解决或使用代理。
data
参数如果是对象,会自动转换为查询字符串(GET)或请求体(POST)。- 在支付宝小程序中,
content-type
为application/json
时需要手动将data
转为 JSON 字符串。
高级用法
对于大型项目,可以进一步封装:
// http.js
const baseURL = 'https://api.example.com';
const http = {
get(url, data) {
return this.request('GET', url, data);
},
post(url, data) {
return this.request('POST', url, data);
},
request(method, url, data) {
return new Promise((resolve, reject) => {
uni.request({
url: baseURL + url,
method,
data,
header: {
'Authorization': `Bearer ${uni.getStorageSync('token')}`
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(res.data);
}
},
fail: (err) => {
reject(err);
}
});
});
}
};
export default http;
// 使用示例
import http from './http.js';
http.get('/users').then(data => {
console.log(data);
}).catch(err => {
console.error(err);
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn