Skip to content

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

js
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

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('Request successful:', res.data);
  },
  fail: (err) => {
    console.error('Request failed:', err);
  }
})

POST Request Example

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('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.

js
// 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.

js
// 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:

js
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.

js
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.

js
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.

js
// 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.

js
// 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.

js
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.

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(`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.

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. API Modularization

Categorize APIs by business modules for easier management and maintenance.

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}`)
};

// 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:

js
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.

  1. Add server domains in the "Development Settings" of the mini program admin panel
  2. 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.

一次开发,多端部署 - 让跨平台开发更简单