網路請求
在 uni-app 中,網路請求是應用開發中非常重要的一部分。本文將詳細介紹如何在 uni-app 中進行網路請求,包括基本用法、進階技巧以及最佳實踐。
uni.request 基礎用法
uni-app 提供了統一的網路請求 API uni.request,可以在各個平台上進行網路請求操作。
基本語法
js
uni.request({
url: 'https://api.example.com/data', // 請求的接口地址
method: 'GET', // 請求方法,可選:GET、POST、PUT、DELETE 等
data: {}, // 請求的參數
header: {}, // 設定請求的 header
success: (res) => {}, // 請求成功後的回調函數
fail: (err) => {}, // 請求失敗後的回調函數
complete: () => {} // 請求完成後的回調函數(無論成功與否)
})GET 請求示例
js
uni.request({
url: 'https://api.example.com/users',
method: 'GET',
data: {
page: 1,
limit: 10
},
header: {
'content-type': 'application/json'
},
success: (res) => {
console.log('請求成功:', res.data);
},
fail: (err) => {
console.error('請求失敗:', err);
}
})POST 請求示例
js
uni.request({
url: 'https://api.example.com/users',
method: 'POST',
data: {
username: 'test',
password: '123456'
},
header: {
'content-type': 'application/json'
},
success: (res) => {
console.log('請求成功:', res.data);
},
fail: (err) => {
console.error('請求失敗:', err);
}
})Promise 風格的網路請求
uni-app 支援使用 Promise 風格的 API,可以讓程式碼更加簡潔。
js
// Promise 方式調用
uni.request({
url: 'https://api.example.com/users',
method: 'GET'
})
.then(res => {
console.log('請求成功:', res[1].data);
})
.catch(err => {
console.error('請求失敗:', err);
})封裝網路請求
在實際專案中,我們通常會對網路請求進行封裝,以便統一處理請求和響應。
js
// request.js
const baseURL = 'https://api.example.com';
// 請求攔截器
const beforeRequest = (config) => {
// 添加 token
const token = uni.getStorageSync('token');
if (token) {
config.header = {
...config.header,
'Authorization': `Bearer ${token}`
};
}
return config;
};
// 響應攔截器
const handleResponse = (res) => {
// 請求成功
if (res.statusCode >= 200 && res.statusCode < 300) {
return res.data;
}
// 未授權
if (res.statusCode === 401) {
uni.showToast({
title: '登入已過期,請重新登入',
icon: 'none'
});
// 跳轉到登入頁
setTimeout(() => {
uni.navigateTo({
url: '/pages/login/login'
});
}, 1500);
return Promise.reject(new Error('未授權'));
}
// 其他錯誤
uni.showToast({
title: res.data.message || '請求失敗',
icon: 'none'
});
return Promise.reject(res);
};
// 封裝請求方法
const request = (options) => {
const config = beforeRequest({
...options,
url: options.url.startsWith('http') ? options.url : baseURL + options.url,
header: options.header || {
'content-type': 'application/json'
}
});
return new Promise((resolve, reject) => {
uni.request({
...config,
success: (res) => {
try {
const data = handleResponse(res);
resolve(data);
} catch (error) {
reject(error);
}
},
fail: (err) => {
uni.showToast({
title: '網路異常,請檢查網路連接',
icon: 'none'
});
reject(err);
}
});
});
};
// 導出請求方法
export default {
get: (url, data, options = {}) => {
return request({
url,
data,
method: 'GET',
...options
});
},
post: (url, data, options = {}) => {
return request({
url,
data,
method: 'POST',
...options
});
},
put: (url, data, options = {}) => {
return request({
url,
data,
method: 'PUT',
...options
});
},
delete: (url, data, options = {}) => {
return request({
url,
data,
method: 'DELETE',
...options
});
}
};使用封裝後的請求方法:
js
import request from '@/utils/request';
// GET 請求
request.get('/users', { page: 1, limit: 10 })
.then(res => {
console.log('獲取用戶列表成功:', res);
})
.catch(err => {
console.error('獲取用戶列表失敗:', err);
});
// POST 請求
request.post('/users', { username: 'test', password: '123456' })
.then(res => {
console.log('創建用戶成功:', res);
})
.catch(err => {
console.error('創建用戶失敗:', err);
});檔案上傳
uni-app 提供了 uni.uploadFile 方法用於檔案上傳。
js
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
formData: {
'user': 'test'
},
success: (res) => {
console.log('上傳成功:', res.data);
},
fail: (err) => {
console.error('上傳失敗:', err);
}
});檔案下載
uni-app 提供了 uni.downloadFile 方法用於檔案下載。
js
uni.downloadFile({
url: 'https://example.com/somefile.pdf',
success: (res) => {
if (res.statusCode === 200) {
console.log('下載成功:', res.tempFilePath);
// 儲存檔案
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
console.log('檔案儲存成功:', saveRes.savedFilePath);
}
});
}
},
fail: (err) => {
console.error('下載失敗:', err);
}
});網路狀態監聽
uni-app 提供了網路狀態監聽的 API,可以即時獲取網路狀態變化。
js
// 獲取當前網路狀態
uni.getNetworkType({
success: (res) => {
console.log('當前網路類型:', res.networkType);
}
});
// 監聽網路狀態變化
uni.onNetworkStatusChange((res) => {
console.log('網路類型:', res.networkType);
console.log('是否有網路連接:', res.isConnected);
});WebSocket 支援
uni-app 提供了 WebSocket 相關的 API,可以實現即時通訊。
js
// 創建 WebSocket 連接
const socketTask = uni.connectSocket({
url: 'wss://example.com/socket',
header: {
'content-type': 'application/json'
},
success: () => {
console.log('WebSocket 連接成功');
}
});
// 監聽 WebSocket 打開
socketTask.onOpen(() => {
console.log('WebSocket 已打開');
// 發送訊息
socketTask.send({
data: JSON.stringify({ type: 'login', data: { userId: '123' } }),
success: () => {
console.log('訊息發送成功');
}
});
});
// 監聽 WebSocket 接收訊息
socketTask.onMessage((res) => {
console.log('收到伺服器訊息:', res.data);
});
// 監聽 WebSocket 錯誤
socketTask.onError((res) => {
console.error('WebSocket 錯誤:', res);
});
// 監聽 WebSocket 關閉
socketTask.onClose(() => {
console.log('WebSocket 已關閉');
});
// 關閉 WebSocket 連接
// socketTask.close();最佳實踐
1. 統一錯誤處理
在網路請求封裝中,統一處理錯誤訊息,避免在每個請求中重複處理。
2. 請求取消
在頁面銷毀時,取消未完成的請求,避免記憶體洩漏。
js
let requestTask = null;
// 發起請求
requestTask = uni.request({
url: 'https://api.example.com/data',
// ...其他配置
});
// 在頁面 onUnload 生命週期中取消請求
onUnload() {
if (requestTask) {
requestTask.abort();
}
}3. 請求重試
對於重要的請求,可以實現請求重試機制。
js
const requestWithRetry = (options, maxRetries = 3) => {
return new Promise((resolve, reject) => {
const attempt = (retryCount) => {
request(options)
.then(resolve)
.catch(error => {
if (retryCount < maxRetries) {
console.log(`請求失敗,第 ${retryCount + 1} 次重試`);
setTimeout(() => {
attempt(retryCount + 1);
}, 1000 * Math.pow(2, retryCount)); // 指數退避策略
} else {
reject(error);
}
});
};
attempt(0);
});
};4. 資料快取
對於不經常變化的資料,可以實現本地快取,減少網路請求。
js
const cachedRequest = (url, expireTime = 60 * 1000) => {
const cacheKey = `cache_${url}`;
const cacheData = uni.getStorageSync(cacheKey);
if (cacheData && cacheData.timestamp) {
const now = new Date().getTime();
if (now - cacheData.timestamp < expireTime) {
return Promise.resolve(cacheData.data);
}
}
return request.get(url).then(res => {
uni.setStorageSync(cacheKey, {
data: res,
timestamp: new Date().getTime()
});
return res;
});
};5. 接口模組化
將接口按照業務模組進行分類,便於管理和維護。
js
// api/user.js
import request from '@/utils/request';
export default {
login: (data) => request.post('/user/login', data),
register: (data) => request.post('/user/register', data),
getUserInfo: () => request.get('/user/info'),
updateUserInfo: (data) => request.put('/user/info', data)
};
// api/product.js
import request from '@/utils/request';
export default {
getProductList: (params) => request.get('/products', params),
getProductDetail: (id) => request.get(`/products/${id}`),
createProduct: (data) => request.post('/products', data),
updateProduct: (id, data) => request.put(`/products/${id}`, data),
deleteProduct: (id) => request.delete(`/products/${id}`)
};
// 使用
import userApi from '@/api/user';
import productApi from '@/api/product';
// 登入
userApi.login({ username: 'test', password: '123456' })
.then(res => {
console.log('登入成功:', res);
});
// 獲取產品列表
productApi.getProductList({ page: 1, limit: 10 })
.then(res => {
console.log('產品列表:', res);
});跨域處理
在開發環境中,可能會遇到跨域問題。uni-app 提供了代理配置來解決跨域問題。
在專案根目錄下創建 vue.config.js 檔案:
js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
};小程式特殊處理
在小程式中,網路請求需要配置合法域名,否則會被攔截。
- 在小程式管理後台的"開發設定"中添加伺服器域名
- 在開發環境中,可以在開發工具中勾選"不校驗合法域名"選項
總結
本文介紹了 uni-app 中網路請求的基本用法、進階技巧以及最佳實踐。通過合理封裝和使用網路請求,可以提高程式碼的可維護性和可複用性,同時也能提升應用的用戶體驗。在實際開發中,應根據專案需求選擇合適的網路請求方式和策略。