阿里云主机折上折
  • 微信号
Current Site:Index > Interface request cross-domain issue

Interface request cross-domain issue

Author:Chuan Chen 阅读数:4652人阅读 分类: uni-app

The Essence of Cross-Origin Issues

Cross-origin problems stem from the browser's same-origin policy restrictions. The same-origin policy requires that the protocol, domain name, and port must be identical to be considered same-origin. In uni-app development, when an application requests an API from a different origin, the browser will intercept the response data. For example:

// Frontend request example (will trigger cross-origin)
uni.request({
  url: 'https://api.other-domain.com/data',
  success: (res) => {
    console.log(res.data)
  }
})

Common Solutions

Backend CORS Configuration

The most standardized solution is to set the Access-Control-Allow-Origin response header on the server side:

// Spring Boot example
@RestController
public class ApiController {
    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Access-Control-Allow-Origin", "*");
        return new ResponseEntity<>("response data", headers, HttpStatus.OK);
    }
}

Proxy Server Solution

Configure vue.config.js in the uni-app project to implement a development environment proxy:

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'https://api.target.com',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}

Use relative paths for actual requests:

uni.request({
  url: '/api/userinfo',  // Actually forwarded to https://api.target.com/userinfo
  method: 'GET'
})

JSONP Solution

Suitable for scenarios requiring only GET requests:

function jsonp(url, callbackName) {
  return new Promise((resolve) => {
    const script = document.createElement('script')
    script.src = `${url}?callback=${callbackName}`
    window[callbackName] = (data) => {
      resolve(data)
      document.body.removeChild(script)
      delete window[callbackName]
    }
    document.body.appendChild(script)
  })
}

// Usage example
jsonp('https://api.example.com/data', 'handleData').then(data => {
  console.log(data)
})

Uni-App-Specific Solutions

Conditional Compilation

Adopt different solutions for different platforms:

// #ifdef H5
// Use proxy in browser environment
const baseURL = '/api'
// #endif

// #ifdef MP-WEIXIN
// Use full URL in Mini Program environment
const baseURL = 'https://api.weixin.com'
// #endif

uni.request({
  url: baseURL + '/user/login'
})

Configuring manifest.json

For WeChat Mini Programs, configure the legal domain in manifest.json:

{
  "mp-weixin": {
    "appid": "",
    "cloud": true,
    "request": {
      "domainWhiteList": [
        "https://api.weixin.com"
      ]
    }
  }
}

Production Environment Deployment Solutions

Nginx Reverse Proxy Configuration

server {
    listen 80;
    server_name yourdomain.com;

    location /api/ {
        proxy_pass https://api.backend.com/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        add_header Access-Control-Allow-Origin *;
    }
}

Cloud Function Relay Solution

Forward requests via uni-cloud cloud functions:

// Cloud function entry file
const cloud = require('wx-server-sdk')
cloud.init()

exports.main = async (event, context) => {
  const res = await cloud.callFunction({
    name: 'httpProxy',
    data: {
      url: 'https://api.target.com/data',
      method: 'POST',
      data: event.data
    }
  })
  return res.result
}

Debugging Tips and Considerations

Disabling Chrome Security Policy

Temporarily disable the same-origin policy during development (local debugging only):

# MacOS
open -n -a "Google Chrome" --args --disable-web-security --user-data-dir=/tmp/chrome

Error Handling Example

Robust error handling mechanism:

uni.request({
  url: 'https://api.example.com/data',
  timeout: 8000,
  fail: (err) => {
    if (err.errMsg.includes('timeout')) {
      uni.showToast({ title: 'Request timeout', icon: 'none' })
    } else if (err.statusCode === 404) {
      uni.showToast({ title: 'API not found', icon: 'none' })
    } else {
      uni.showToast({ title: 'Network error', icon: 'none' })
    }
  }
})

Special Scenario Handling

Cross-Origin File Uploads

Additional handling for withCredentials:

uni.uploadFile({
  url: 'https://api.example.com/upload',
  filePath: tempFilePath,
  name: 'file',
  header: {
    'Content-Type': 'multipart/form-data'
  },
  withCredentials: true  // Set when cookies need to be included
})

WebSocket Cross-Origin

WebSocket is not restricted by the same-origin policy but is subject to permission controls:

const socket = new WebSocket('wss://api.example.com/ws')

socket.onopen = () => {
  console.log('Connection successful')
  socket.send(JSON.stringify({type: 'ping'}))
}

socket.onmessage = (e) => {
  console.log('Message received:', e.data)
}

Security Recommendations

Protecting Sensitive Information

Avoid hardcoding sensitive information in the frontend:

// Not recommended
const API_KEY = '123456abcdef'

// Recommended: Obtain via backend API
uni.request({
  url: '/getApiKey',
  success: (res) => {
    const key = res.data.key
    // Use the obtained key
  }
})

HTTPS Requirement

Modern browsers enforce strict mixed-content restrictions:

# Enforce HTTPS
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.