Network Requests
Network requests are a crucial part of application development in uni-app. This article will detail how to perform network requests in uni-app, including basic usage, advanced techniques, and best practices.
uni.request Basic Usage
uni-app provides a unified network request API uni.request
that can be used across all platforms.
Basic Syntax
uni.request({
url: 'https://api.example.com/data', // API endpoint
method: 'GET', // Request method: GET, POST, PUT, DELETE, etc.
data: {}, // Request parameters
header: {}, // Request headers
success: (res) => {}, // Success callback
fail: (err) => {}, // Failure callback
complete: () => {} // Completion callback (regardless of success or failure)
})
GET Request Example
uni.request({
url: 'https://api.example.com/users',
method: 'GET',
data: {
page: 1,
limit: 10
},
header: {
'content-type': 'application/json'
},
success: (res) => {
console.log('Request successful:', res.data);
},
fail: (err) => {
console.error('Request failed:', err);
}
})
POST Request Example
uni.request({
url: 'https://api.example.com/users',
method: 'POST',
data: {
username: 'test',
password: '123456'
},
header: {
'content-type': 'application/json'
},
success: (res) => {
console.log('Request successful:', res.data);
},
fail: (err) => {
console.error('Request failed:', err);
}
})
Promise-style Network Requests
uni-app supports Promise-style APIs, which can make your code more concise.
// Promise approach
uni.request({
url: 'https://api.example.com/users',
method: 'GET'
})
.then(res => {
console.log('Request successful:', res[1].data);
})
.catch(err => {
console.error('Request failed:', err);
})
Encapsulating Network Requests
In real projects, we typically encapsulate network requests to handle requests and responses uniformly.
// request.js
const baseURL = 'https://api.example.com';
// Request interceptor
const beforeRequest = (config) => {
// Add token
const token = uni.getStorageSync('token');
if (token) {
config.header = {
...config.header,
'Authorization': `Bearer ${token}`
};
}
return config;
};
// Response interceptor
const handleResponse = (res) => {
// Request successful
if (res.statusCode >= 200 && res.statusCode < 300) {
return res.data;
}
// Unauthorized
if (res.statusCode === 401) {
uni.showToast({
title: 'Login expired, please log in again',
icon: 'none'
});
// Navigate to login page
setTimeout(() => {
uni.navigateTo({
url: '/pages/login/login'
});
}, 1500);
return Promise.reject(new Error('Unauthorized'));
}
// Other errors
uni.showToast({
title: res.data.message || 'Request failed',
icon: 'none'
});
return Promise.reject(res);
};
// Encapsulated request method
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: 'Network exception, please check your connection',
icon: 'none'
});
reject(err);
}
});
});
};
// Export request methods
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
});
}
};
Using the encapsulated request methods:
import request from '@/utils/request';
// GET request
request.get('/users', { page: 1, limit: 10 })
.then(res => {
console.log('Get user list successful:', res);
})
.catch(err => {
console.error('Get user list failed:', err);
});
// POST request
request.post('/users', { username: 'test', password: '123456' })
.then(res => {
console.log('Create user successful:', res);
})
.catch(err => {
console.error('Create user failed:', err);
});
File Upload
uni-app provides the uni.uploadFile
method for file uploads.
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
formData: {
'user': 'test'
},
success: (res) => {
console.log('Upload successful:', res.data);
},
fail: (err) => {
console.error('Upload failed:', err);
}
});
File Download
uni-app provides the uni.downloadFile
method for file downloads.
uni.downloadFile({
url: 'https://example.com/somefile.pdf',
success: (res) => {
if (res.statusCode === 200) {
console.log('Download successful:', res.tempFilePath);
// Save file
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
console.log('File saved successfully:', saveRes.savedFilePath);
}
});
}
},
fail: (err) => {
console.error('Download failed:', err);
}
});
Network Status Monitoring
uni-app provides APIs for monitoring network status to get real-time network status changes.
// Get current network status
uni.getNetworkType({
success: (res) => {
console.log('Current network type:', res.networkType);
}
});
// Monitor network status changes
uni.onNetworkStatusChange((res) => {
console.log('Network type:', res.networkType);
console.log('Is connected:', res.isConnected);
});
WebSocket Support
uni-app provides WebSocket-related APIs for real-time communication.
// Create WebSocket connection
const socketTask = uni.connectSocket({
url: 'wss://example.com/socket',
header: {
'content-type': 'application/json'
},
success: () => {
console.log('WebSocket connection successful');
}
});
// Listen for WebSocket open
socketTask.onOpen(() => {
console.log('WebSocket opened');
// Send message
socketTask.send({
data: JSON.stringify({ type: 'login', data: { userId: '123' } }),
success: () => {
console.log('Message sent successfully');
}
});
});
// Listen for WebSocket messages
socketTask.onMessage((res) => {
console.log('Received server message:', res.data);
});
// Listen for WebSocket errors
socketTask.onError((res) => {
console.error('WebSocket error:', res);
});
// Listen for WebSocket close
socketTask.onClose(() => {
console.log('WebSocket closed');
});
// Close WebSocket connection
// socketTask.close();
Best Practices
1. Unified Error Handling
In network request encapsulation, handle error messages uniformly to avoid repetitive handling in each request.
2. Request Cancellation
Cancel unfinished requests when a page is destroyed to avoid memory leaks.
let requestTask = null;
// Initiate request
requestTask = uni.request({
url: 'https://api.example.com/data',
// ...other configurations
});
// Cancel request in page onUnload lifecycle
onUnload() {
if (requestTask) {
requestTask.abort();
}
}
3. Request Retry
Implement a retry mechanism for important requests.
const requestWithRetry = (options, maxRetries = 3) => {
return new Promise((resolve, reject) => {
const attempt = (retryCount) => {
request(options)
.then(resolve)
.catch(error => {
if (retryCount < maxRetries) {
console.log(`Request failed, retry ${retryCount + 1}`);
setTimeout(() => {
attempt(retryCount + 1);
}, 1000 * Math.pow(2, retryCount)); // Exponential backoff strategy
} else {
reject(error);
}
});
};
attempt(0);
});
};
4. Data Caching
Implement local caching for data that doesn't change frequently to reduce network requests.
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. API Modularization
Categorize APIs by business modules for easier management and maintenance.
// 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}`)
};
// Usage
import userApi from '@/api/user';
import productApi from '@/api/product';
// Login
userApi.login({ username: 'test', password: '123456' })
.then(res => {
console.log('Login successful:', res);
});
// Get product list
productApi.getProductList({ page: 1, limit: 10 })
.then(res => {
console.log('Product list:', res);
});
Cross-Origin Handling
In the development environment, you may encounter cross-origin issues. uni-app provides proxy configuration to solve cross-origin problems.
Create a vue.config.js
file in the project root directory:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
};
Special Handling for Mini Programs
In mini programs, network requests need to configure valid domains, otherwise they will be blocked.
- Add server domains in the "Development Settings" of the mini program admin panel
- In the development environment, you can check the "Don't validate valid domains" option in the development tool
Summary
This article introduced the basic usage, advanced techniques, and best practices of network requests in uni-app. By properly encapsulating and using network requests, you can improve the maintainability and reusability of your code, while also enhancing the user experience of your application. In actual development, choose appropriate network request methods and strategies based on project requirements.