Network Request Issues
This page collects common issues and solutions related to uni-app network requests.
Basic Request Issues
Q: Requests cannot be sent or timeout
Problem Description: Network requests cannot be sent or frequently timeout.
Solutions:
- Check if network connection is normal
- Check if request URL is correct, especially the protocol part (http/https)
- Increase request timeout:js
uni.request({ url: 'https://api.example.com/data', timeout: 10000, // Set longer timeout (10 seconds) success: (res) => { console.log(res.data); }, fail: (err) => { console.error('Request failed', err); } });
- Implement request retry mechanism:js
function requestWithRetry(options, maxRetries = 3) { let retryCount = 0; function sendRequest() { uni.request({ ...options, fail: (err) => { if (retryCount < maxRetries) { retryCount++; console.log(`Request failed, retry ${retryCount}`); setTimeout(sendRequest, 1000 * retryCount); } else if (options.fail) { options.fail(err); } } }); } sendRequest(); }
Q: Requests return 404, 500 and other errors
Problem Description: Requests return HTTP error status codes.
Solutions:
- Check if request URL is correct
- Check if server is running normally
- Check if request parameters meet interface requirements
- Implement error handling logic:js
uni.request({ url: 'https://api.example.com/data', success: (res) => { if (res.statusCode === 200) { // Request successful console.log(res.data); } else { // Handle different error status codes switch (res.statusCode) { case 404: console.error('Resource not found'); break; case 401: console.error('Unauthorized, please login'); // Navigate to login page uni.navigateTo({ url: '/pages/login/login' }); break; case 500: console.error('Internal server error'); break; default: console.error(`Request error: ${res.statusCode}`); } } }, fail: (err) => { console.error('Request failed', err); } });
CORS Issues
Q: H5 request CORS issues
Problem Description: Encountering CORS restrictions when making requests on H5 platform.
Solutions:
- Set CORS headers on server side:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization
- Configure proxy in manifest.json:json
{ "h5": { "devServer": { "port": 8080, "disableHostCheck": true, "proxy": { "/api": { "target": "https://api.example.com", "changeOrigin": true, "pathRewrite": { "^/api": "" } } } } } }
- Use JSONP for requests (only for GET requests)
- Use server-side proxy for requests
Q: Mini Program domain restrictions
Problem Description: Mini Program requests show unauthorized domain error.
Solutions:
- Add server domain to whitelist in Mini Program admin console
- During development, check "Do not verify legal domains" in developer tools
- Use Mini Program cloud functions to proxy requests
- Ensure request URLs use HTTPS protocol
Data Format Issues
Q: Request data format errors
Problem Description: Server cannot correctly parse request data.
Solutions:
- Check if request header Content-Type is correctly set:js
uni.request({ url: 'https://api.example.com/data', method: 'POST', header: { 'Content-Type': 'application/json' }, data: JSON.stringify(postData), success: (res) => { console.log(res.data); } });
- Ensure data format meets interface requirements
- Check if special characters need encoding
- Use uni.request's dataType parameter to specify response data type
Q: Response data parsing errors
Problem Description: Cannot correctly parse data returned by server.
Solutions:
- Check if response data format meets expectations
- Use dataType parameter to specify response data type:js
uni.request({ url: 'https://api.example.com/data', dataType: 'json', // Specify response data as JSON format success: (res) => { console.log(res.data); } });
- Manually parse response data:js
uni.request({ url: 'https://api.example.com/data', success: (res) => { try { const data = JSON.parse(res.data); console.log(data); } catch (e) { console.error('Data parsing error', e); } } });
- Check if server returns correct data encoding
Authorization and Authentication Issues
Q: Requests need to carry authentication information
Problem Description: Requests need to carry token or other authentication information.
Solutions:
- Add authentication information in request headers:js
const token = uni.getStorageSync('token'); uni.request({ url: 'https://api.example.com/data', header: { 'Authorization': `Bearer ${token}` }, success: (res) => { console.log(res.data); } });
- Implement request interceptor to uniformly add authentication information:js
// request.js const request = (options) => { // Clone original options const requestOptions = { ...options }; // Add base URL requestOptions.url = baseUrl + requestOptions.url; // Add request headers requestOptions.header = { ...requestOptions.header, 'Authorization': `Bearer ${uni.getStorageSync('token')}` }; // Send request return new Promise((resolve, reject) => { uni.request({ ...requestOptions, success: (res) => { if (res.statusCode === 200) { resolve(res.data); } else if (res.statusCode === 401) { // Handle authentication failure uni.navigateTo({ url: '/pages/login/login' }); reject(new Error('Authentication failed')); } else { reject(new Error(`Request failed: ${res.statusCode}`)); } }, fail: (err) => { reject(err); } }); }); };
- Use cookies to store session information (requires server support)
- Implement token refresh mechanism to handle expiration
Q: Login status expiration issues
Problem Description: User login status expires, requiring re-login.
Solutions:
- Implement token expiration detection and automatic refresh:js
// Check if token is expired function isTokenExpired(token) { if (!token) return true; try { // Assume token is JWT format const payload = JSON.parse(atob(token.split('.')[1])); return payload.exp < Date.now() / 1000; } catch (e) { return true; } } // Refresh token async function refreshToken() { try { const refreshToken = uni.getStorageSync('refreshToken'); const res = await uni.request({ url: 'https://api.example.com/refresh', method: 'POST', data: { refreshToken } }); if (res.statusCode === 200) { uni.setStorageSync('token', res.data.token); uni.setStorageSync('refreshToken', res.data.refreshToken); return res.data.token; } else { throw new Error('Token refresh failed'); } } catch (e) { // Refresh failed, need to re-login uni.removeStorageSync('token'); uni.removeStorageSync('refreshToken'); uni.navigateTo({ url: '/pages/login/login' }); throw e; } }
- Uniformly handle 401 errors, automatically redirect to login page
- Implement session persistence mechanism, regularly refresh token
- Use local storage to save user information, reduce repeated logins
Request Management and Optimization
Q: How to cancel ongoing requests
Problem Description: Need to cancel requests that have been sent but not yet completed.
Solutions:
- Use requestTask object to cancel requests:js
const requestTask = uni.request({ url: 'https://api.example.com/data', success: (res) => { console.log(res.data); } }); // Cancel request requestTask.abort();
- Implement request manager to track and cancel requests:js
class RequestManager { constructor() { this.requests = new Map(); } // Add request addRequest(key, requestTask) { this.requests.set(key, requestTask); } // Remove request removeRequest(key) { this.requests.delete(key); } // Cancel request cancelRequest(key) { const requestTask = this.requests.get(key); if (requestTask) { requestTask.abort(); this.removeRequest(key); } } // Cancel all requests cancelAllRequests() { this.requests.forEach(requestTask => { requestTask.abort(); }); this.requests.clear(); } } // Use request manager const requestManager = new RequestManager(); function sendRequest(url, key) { const requestTask = uni.request({ url, complete: () => { requestManager.removeRequest(key); } }); requestManager.addRequest(key, requestTask); return requestTask; } // Cancel all requests when page unloads onUnload() { requestManager.cancelAllRequests(); }
- Actively cancel requests when page switches or component unmounts
- Use timeout mechanism to automatically cancel long unresponsive requests
Q: How to handle concurrent request limits
Problem Description: Sending many requests simultaneously causes performance issues or server rate limiting.
Solutions:
- Implement request queue to control concurrency:js
class RequestQueue { constructor(maxConcurrent = 5) { this.queue = []; this.running = 0; this.maxConcurrent = maxConcurrent; } add(requestFn) { return new Promise((resolve, reject) => { this.queue.push({ requestFn, resolve, reject }); this.run(); }); } run() { if (this.running >= this.maxConcurrent || this.queue.length === 0) { return; } const { requestFn, resolve, reject } = this.queue.shift(); this.running++; requestFn() .then(resolve) .catch(reject) .finally(() => { this.running--; this.run(); }); } } // Use request queue const requestQueue = new RequestQueue(3); function sendRequest(url) { return requestQueue.add(() => { return new Promise((resolve, reject) => { uni.request({ url, success: resolve, fail: reject }); }); }); }
- Merge requests to reduce request count
- Use batch APIs to get multiple data at once
- Implement request throttling to avoid repeated requests for same resource in short time
Network Status Management
Q: How to handle weak network or offline situations
Problem Description: Request failures in unstable network or offline situations affect user experience.
Solutions:
- Monitor network status changes:js
// Monitor network status uni.onNetworkStatusChange(function(res) { console.log(`Network type: ${res.networkType}`); console.log(`Is connected: ${res.isConnected}`); if (res.isConnected) { // Network restored, can resend failed requests resendFailedRequests(); } else { // Network disconnected, notify user uni.showToast({ title: 'Network connection lost', icon: 'none' }); } }); // Get current network status uni.getNetworkType({ success: (res) => { console.log(`Current network type: ${res.networkType}`); } });
- Implement offline data caching and synchronization:js
// Request function with offline cache async function requestWithCache(url, options = {}) { const cacheKey = `cache_${url}`; try { // Check network status const networkStatus = await getNetworkStatus(); if (networkStatus.isConnected) { // Has network, send request const response = await sendRequest(url, options); // Cache response data uni.setStorageSync(cacheKey, { data: response.data, timestamp: Date.now() }); return response.data; } else { // No network, use cache const cache = uni.getStorageSync(cacheKey); if (cache) { console.log(`Using cached data: ${url}`); return cache.data; } else { throw new Error('No network connection and no cached data'); } } } catch (error) { // Request failed, try using cache const cache = uni.getStorageSync(cacheKey); if (cache) { console.log(`Request failed, using cached data: ${url}`); return cache.data; } else { throw error; } } }
- Provide offline mode, allow users to browse cached content when offline
- Implement request queue to automatically resend failed requests when network recovers
Q: How to optimize user experience in weak network environments
Problem Description: Slow requests in unstable network environments affect user experience.
Solutions:
- Implement progressive loading, show skeleton screens or placeholder content first
- Prioritize loading critical data, delay loading non-critical content
- Reduce request data size, use pagination or on-demand loading
- Provide loading status feedback:js
// Request function with loading status async function requestWithLoading(url, options = {}) { const showLoading = options.showLoading !== false; if (showLoading) { uni.showLoading({ title: options.loadingText || 'Loading...', mask: options.loadingMask || false }); } try { const response = await sendRequest(url, options); return response; } finally { if (showLoading) { uni.hideLoading(); } } }
File Upload and Download
Q: File upload failure or interruption
Problem Description: File upload fails or gets interrupted.
Solutions:
- Use chunked upload for large files:js
// Upload file in chunks async function uploadFileInChunks(filePath, options = {}) { const chunkSize = options.chunkSize || 1024 * 1024; // Default 1MB per chunk const fileInfo = await getFileInfo(filePath); const totalSize = fileInfo.size; const chunks = Math.ceil(totalSize / chunkSize); // Create upload task const uploadId = await createUploadTask(fileInfo.name, totalSize); // Upload chunks for (let i = 0; i < chunks; i++) { const start = i * chunkSize; const end = Math.min(start + chunkSize, totalSize); await uploadChunk({ filePath, uploadId, chunkIndex: i, start, end }); // Update progress if (options.onProgress) { options.onProgress({ progress: Math.floor((i + 1) / chunks * 100), totalChunks: chunks, currentChunk: i + 1 }); } } // Complete upload return await completeUpload(uploadId); }
- Implement resumable upload:js
// Resumable upload async function resumableUpload(filePath, options = {}) { const fileInfo = await getFileInfo(filePath); const uploadKey = `upload_${fileInfo.name}_${fileInfo.size}`; // Try to get upload progress let uploadProgress = uni.getStorageSync(uploadKey) || { uploadId: null, uploadedChunks: [] }; // If no upload ID or upload expired, create new upload task if (!uploadProgress.uploadId) { uploadProgress.uploadId = await createUploadTask(fileInfo.name, fileInfo.size); uploadProgress.uploadedChunks = []; } // Calculate remaining chunks to upload const chunkSize = options.chunkSize || 1024 * 1024; const totalChunks = Math.ceil(fileInfo.size / chunkSize); const remainingChunks = []; for (let i = 0; i < totalChunks; i++) { if (!uploadProgress.uploadedChunks.includes(i)) { remainingChunks.push(i); } } // Upload remaining chunks for (const chunkIndex of remainingChunks) { const start = chunkIndex * chunkSize; const end = Math.min(start + chunkSize, fileInfo.size); await uploadChunk({ filePath, uploadId: uploadProgress.uploadId, chunkIndex, start, end }); // Update uploaded chunks record uploadProgress.uploadedChunks.push(chunkIndex); uni.setStorageSync(uploadKey, uploadProgress); // Update progress if (options.onProgress) { options.onProgress({ progress: Math.floor(uploadProgress.uploadedChunks.length / totalChunks * 100), totalChunks, uploadedChunks: uploadProgress.uploadedChunks.length }); } } // Complete upload const result = await completeUpload(uploadProgress.uploadId); // Clean upload record uni.removeStorageSync(uploadKey); return result; }
- Add retry mechanism, automatically retry failed uploads
- Optimize upload parameters like timeout and concurrency
Q: File download issues
Problem Description: File download fails or downloaded files cannot be opened.
Solutions:
- Use uni.downloadFile API to download files:js
// Download file with progress display function downloadFile(url, options = {}) { const downloadTask = uni.downloadFile({ url, header: options.header, timeout: options.timeout || 60000, success: (res) => { if (res.statusCode === 200) { console.log('Download successful', res.tempFilePath); if (options.saveFile) { // Save file locally uni.saveFile({ tempFilePath: res.tempFilePath, success: (saveRes) => { console.log('File saved', saveRes.savedFilePath); if (options.success) options.success(saveRes.savedFilePath); }, fail: (err) => { console.error('Save file failed', err); if (options.fail) options.fail(err); } }); } else if (options.success) { options.success(res.tempFilePath); } } else { console.error('Download failed', res); if (options.fail) options.fail(new Error(`Download failed: ${res.statusCode}`)); } }, fail: (err) => { console.error('Download failed', err); if (options.fail) options.fail(err); } }); // Monitor download progress if (options.onProgress) { downloadTask.onProgressUpdate((res) => { options.onProgress({ progress: res.progress, totalBytesWritten: res.totalBytesWritten, totalBytesExpectedToWrite: res.totalBytesExpectedToWrite }); }); } return downloadTask; }
- Check file save path and permissions
- Implement chunked download for large files
- Add file integrity verification like MD5 checksum
Best Practices
Request Encapsulation and Unified Handling
Encapsulate request functions, uniformly handle errors and responses:
js// request.js // Basic configuration const config = { baseUrl: 'https://api.example.com', timeout: 10000, header: { 'Content-Type': 'application/json' } }; // Request interceptors const requestInterceptors = []; // Response interceptors const responseInterceptors = []; // Add request interceptor function addRequestInterceptor(interceptor) { requestInterceptors.push(interceptor); } // Add response interceptor function addResponseInterceptor(interceptor) { responseInterceptors.push(interceptor); } // Process request configuration function processRequestConfig(options) { let processedOptions = { ...config, ...options }; // Apply request interceptors for (const interceptor of requestInterceptors) { processedOptions = interceptor(processedOptions); } return processedOptions; } // Process response data function processResponse(response, options) { let processedResponse = response; // Apply response interceptors for (const interceptor of responseInterceptors) { processedResponse = interceptor(processedResponse, options); } return processedResponse; } // Request function function request(options) { const processedOptions = processRequestConfig(options); return new Promise((resolve, reject) => { uni.request({ ...processedOptions, success: (res) => { const processedResponse = processResponse(res, processedOptions); if (processedResponse.statusCode >= 200 && processedResponse.statusCode < 300) { resolve(processedResponse.data); } else { reject(processedResponse); } }, fail: (err) => { reject(err); } }); }); } // Export request methods export default { request, get: (url, data, options = {}) => request({ url, data, method: 'GET', ...options }), post: (url, data, options = {}) => request({ url, data, method: 'POST', ...options }), put: (url, data, options = {}) => request({ url, data, method: 'PUT', ...options }), delete: (url, data, options = {}) => request({ url, data, method: 'DELETE', ...options }), addRequestInterceptor, addResponseInterceptor };
Add global error handling:
js// Add global error handling interceptor addResponseInterceptor((response) => { if (response.statusCode === 401) { // Handle unauthorized error uni.showToast({ title: 'Login expired, please login again', icon: 'none' }); // Navigate to login page setTimeout(() => { uni.navigateTo({ url: '/pages/login/login' }); }, 1500); } else if (response.statusCode >= 500) { // Handle server error uni.showToast({ title: 'Server error, please try again later', icon: 'none' }); } return response; });
Data Caching Strategy
Implement data caching and expiration control:
js// cache.js // Cache data to local storage function setCache(key, data, expireTime = 3600) { uni.setStorageSync(key, { data, expireAt: Date.now() + expireTime * 1000 }); } // Get cached data function getCache(key) { const cache = uni.getStorageSync(key); if (!cache) return null; // Check if expired if (cache.expireAt && cache.expireAt < Date.now()) { uni.removeStorageSync(key); return null; } return cache.data; } // Request function with cache async function requestWithCache(url, options = {}) { const cacheKey = `cache_${url}_${JSON.stringify(options.data || {})}`; const useCache = options.useCache !== false; const cacheTime = options.cacheTime || 300; // Default cache 5 minutes // If cache enabled, try to get from cache if (useCache) { const cachedData = getCache(cacheKey); if (cachedData) { return cachedData; } } // Send request const response = await request({ url, ...options }); // Cache response data if (useCache) { setCache(cacheKey, response, cacheTime); } return response; }
Implement data preloading:
js// Preload common data function preloadCommonData() { // Preload user info requestWithCache('/api/user/info', { cacheTime: 3600 }); // Preload app config requestWithCache('/api/config', { cacheTime: 86400 }); // Preload other common data // ... } // Call on app startup // App.vue onLaunch() { preloadCommonData(); }
If you cannot find a solution to your problem on this page, please check the uni-app official documentation or seek help in the uni-app community.
Common Error Code Analysis
Network Request Error Codes
Error Code | Description | Possible Causes | Solutions |
---|---|---|---|
-1 | Unknown error | Network exception, request timeout, etc. | Check network connection, increase timeout |
401 | Unauthorized | User not logged in or token expired | Re-login to get new token |
403 | Forbidden | User has no permission to access resource | Check user permission settings |
404 | Not found | URL error or resource deleted | Check if request URL is correct |
500 | Internal server error | Server-side code exception | Contact backend developers to fix |
502 | Bad gateway | Server restart or load balancer issues | Retry later or contact service provider |
503 | Service unavailable | Server maintenance or overload | Retry later |
Mini Program Request Specific Errors
Error Code | Description | Possible Causes | Solutions |
---|---|---|---|
12000 | Network error | Network connection failed | Check network connection |
12001 | Request timeout | Server response time too long | Increase timeout or optimize server response speed |
12002 | Request blocked | Domain not configured or invalid HTTPS certificate | Check domain configuration and HTTPS certificate |
12003 | Resource not found | URL error | Check request URL |
12006 | Request interrupted | Called abort method or network disconnected | Check if code actively interrupts request |
Debugging Tips
Network Request Debugging
Use console to view requests:
- Use console.log in HBuilderX to print request parameters and response results
- Use Network panel in WeChat Developer Tools to view request details
Add debug logs:
js// Add request log interceptor addRequestInterceptor((options) => { console.log('Request parameters:', options); return options; }); // Add response log interceptor addResponseInterceptor((response, options) => { console.log(`Request ${options.url} response:`, response); return response; });
Use packet capture tools:
- Use Charles, Fiddler and other tools to capture and analyze requests and responses
- Use proxy method for packet capture on App platform
Common Problem Troubleshooting Process
Request cannot be sent:
- Check network connection
- Check if request URL is correct
- Check if Mini Program domain is configured
- Check if HTTPS certificate is valid
Request sent but no response:
- Check if request timed out
- Check if server is running normally
- Check if firewall or security policies are blocking
Request returns error:
- Check if request parameters are correct
- Check if authentication information is valid
- Check server logs to understand specific errors
Data parsing error:
- Check response data format
- Check if dataType parameter is correct
- Check if special characters cause parsing failure
Performance Optimization Suggestions
Reduce request count:
- Merge multiple requests
- Use batch APIs
- Implement data caching strategy
Reduce request data size:
- Only request necessary data
- Use pagination loading
- Compress request and response data
Optimize request timing:
- Avoid duplicate requests
- Implement request throttling and debouncing
- Preload potentially needed data
Optimize error handling:
- Implement graceful degradation strategies
- Provide friendly error messages
- Automatically retry non-critical requests