全篇大概 3600 字(含代码),建议阅读时间 25min
📚 目录
- 使用uni.request发起请求
- 封装全局请求工具
- 破解跨域难题
- 总结
在跨平台应用开发中,网络请求是连接前端与后端服务的核心环节。UniApp 提供了 uni.request
方法处理网络请求,但在实际项目中,我们还需要处理全局封装、错误处理和跨域等实际问题。本文将带您全面掌握 UniApp 网络请求的实战技巧。
1、使用 uni.request 发起请求
1.1 基本用法
uni.request
是 UniApp 的核心 API,支持所有主流平台。
基础用法如下:
// 发起 GET 请求
uni.request({
url: '接口',
method: 'GET',
success: (res) => {
console.log('响应数据:', res.data);
},
fail: (err) => {
console.error('请求失败:', err);
}
});
// 发起 POST 请求
uni.request({
url: '接口',
method: 'POST',
data: { name: 'John', age: 25 },
header: { 'Content-Type': 'application/json' },
success: (res) => {
console.log('提交成功:', res.data);
}
});
1.2 实战示例:获取天气数据
function getWeather(city) {
uni.request({
url: '接口',
data: { city: city },
success: (res) => {
if (res.statusCode === 200) {
console.log('当前温度:', res.data.temperature);
} else {
uni.showToast({ title: '数据获取失败', icon: 'none' });
}
},
fail: () => {
uni.showToast({ title: '网络连接失败', icon: 'none' });
}
});
}
2. 封装全局请求工具
2.1 为什么要封装?
- 统一处理
错误
和加载状态
- 集中管理
请求头
(如 Token) 简化业务
代码调用
2.2 完整封装方案
创建 utils/http.js
:
class HttpRequest {
constructor() {
this.baseUrl = '接口';
this.timeout = 10000;
}
request(config) {
return new Promise((resolve, reject) => {
// 请求拦截
const fullUrl = this.baseUrl + config.url;
const header = this.getHeaders(config.headers);
uni.request({
url: fullUrl,
method: config.method || 'GET',
data: config.data,
header: header,
timeout: this.timeout,
success: (res) => {
// 响应拦截
if (res.statusCode === 200) {
resolve(res.data);
} else {
this.handleError(res);
reject(res);
}
},
fail: (err) => {
this.handleError(err);
reject(err);
}
});
});
}
getHeaders(customHeaders) {
const headers = {
'Content-Type': 'application/json',
'X-Client-Type': 'uniapp'
};
// 添加认证 Token
const token = uni.getStorageSync('authToken');
if (token) headers.Authorization = `Bearer ${token}`;
return { ...headers, ...customHeaders };
}
handleError(error) {
const status = error.statusCode;
let message = '请求失败';
if (status === 401) {
message = '登录已过期';
uni.navigateTo({ url: '/pages/login/login' });
} else if (status >= 500) {
message = '服务器异常,请稍后再试';
}
uni.showToast({ title: message, icon: 'none' });
}
get(url, params) {
return this.request({ method: 'GET', url, data: params });
}
post(url, data) {
return this.request({ method: 'POST', url, data });
}
}
export default new HttpRequest();
2.3 使用示例
import http from '@/utils/http';
// 获取用户信息
async function fetchUser() {
try {
const user = await http.get('/user/profile');
console.log('用户数据:', user);
} catch (e) {
console.error('请求异常:', e);
}
}
// 提交表单
async function submitForm(data) {
await http.post('/form/submit', data);
uni.showToast({ title: '提交成功' });
}
3. 破解跨域难题
3.1 跨域原理
浏览器安全策略限制不同源(协议+域名+端口)的请求,主要影响H5端,小程序/App端无此限制。
3.2 解决方案对比
方案 | 适用环境 | 优点 | 缺点 |
---|---|---|---|
开发代理 | 本地开发 | 无需后端配合 | 仅限开发环境 |
CORS | 生产环境 | 标准解决方案 | 需要后端配置 |
JSONP | 简单请求 | 兼容旧浏览器 | 仅支持GET |
Nginx代理 | 生产环境 | 前端无需修改 | 需服务器配置 |
3.3 实战配置指南
方案一:开发环境代理(HBuilderX)
配置 manifest.json
:
{
"h5": {
"devServer": {
"proxy": {
"/api": {
"target": "接口",
"changeOrigin": true,
"pathRewrite": {"^/api": ""}
}
}
}
}
}
方案二:生产环境CORS
Node.js
示例:
// Express 中间件
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Authorization, Content-Type');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
next();
});
方案三:Nginx
反向代理
server {
listen 80;
server_name 域名;
location /api/ {
proxy_pass 接口;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
4. 总结
分层架构
:通过封装实现业务逻辑与网络层的解耦
异常处理
:统一处理401等状态码,增强用户体验
安全策略
:HTTPS请求、Token刷新机制、请求签名
性能优化
:合理设置超时时间(建议10-30秒),重要请求增加重试机制,大数据量使用分页加载
// 示例:请求重试机制
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await http.get(url);
} catch (err) {
if (i === retries - 1) throw err;
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
通过合理封装
和正确配置
,可以在UniApp
中构建稳定高效的网络请求体系。建议根据实际项目需求调整封装方案,并做好各平台的兼容性测试。