跳转到内容

跨域问题解决

来自代码酷

跨域问题解决[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

跨域问题(Cross-Origin Resource Sharing, CORS)是浏览器基于同源策略(Same-Origin Policy)的安全机制所导致的一种限制。当网页尝试从不同协议(HTTP/HTTPS)、不同域名或不同端口请求资源时,浏览器会阻止该请求,除非服务器明确允许跨域访问。

同源策略要求以下三个部分必须完全相同:

  • 协议(Protocol)
  • 域名(Domain)
  • 端口(Port)

例如:

解决方案[编辑 | 编辑源代码]

以下是常见的跨域解决方案:

1. CORS(跨域资源共享)[编辑 | 编辑源代码]

CORS 是 W3C 标准,允许服务器声明哪些源可以访问其资源。服务器通过 HTTP 头(如 Access-Control-Allow-Origin)控制跨域请求。

服务器端配置[编辑 | 编辑源代码]

在服务器端(如 Node.js + Express),可以设置如下:

const express = require('express');
const app = express();

// 允许所有来源访问
app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    next();
});

app.get('/api/data', (req, res) => {
    res.json({ message: 'CORS 已启用!' });
});

app.listen(3000, () => console.log('服务器运行中...'));

浏览器行为[编辑 | 编辑源代码]

浏览器在发送跨域请求时,会先发送一个 预检请求(Preflight Request,OPTIONS 方法)检查服务器是否允许该请求。

sequenceDiagram Browser->>Server: OPTIONS /api/data (预检请求) Server-->>Browser: 返回允许的 Origin/Methods/Headers Browser->>Server: GET /api/data (实际请求) Server-->>Browser: 返回数据

2. JSONP(JSON with Padding)[编辑 | 编辑源代码]

JSONP 利用 <script> 标签不受同源策略限制的特性,动态创建脚本加载跨域数据。

// 客户端代码
function handleResponse(data) {
    console.log('收到数据:', data);
}

const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleResponse';
document.body.appendChild(script);

服务器响应[编辑 | 编辑源代码]

服务器返回的数据需包裹在回调函数中:

handleResponse({ message: 'JSONP 数据' });

缺点:仅支持 GET 请求,且存在安全风险(如 XSS)。

3. 代理服务器[编辑 | 编辑源代码]

通过同源的后端服务器转发请求,绕过浏览器限制。

Nginx 配置示例[编辑 | 编辑源代码]

server {
    listen 80;
    server_name localhost;

    location /api {
        proxy_pass https://api.example.com;
        proxy_set_header Host $host;
    }
}

4. WebSocket[编辑 | 编辑源代码]

WebSocket 协议不受同源策略限制,适用于实时通信场景。

const socket = new WebSocket('wss://api.example.com');
socket.onmessage = (event) => {
    console.log('收到消息:', event.data);
};

实际案例[编辑 | 编辑源代码]

案例 1:前端调用第三方 API[编辑 | 编辑源代码]

假设你的网站(https://myapp.com)需要调用天气 API(https://api.weather.com):

  • 若 API 支持 CORS,直接调用即可。
  • 若不支持,需使用代理或 JSONP(如果 API 提供该方式)。

案例 2:开发环境跨域[编辑 | 编辑源代码]

在本地开发时(http://localhost:3000),访问后端(http://localhost:8080)可能触发跨域。解决方案:

  • 后端设置 Access-Control-Allow-Origin: http://localhost:3000
  • 使用开发服务器代理(如 webpack-dev-server 的 proxy 配置)

安全注意事项[编辑 | 编辑源代码]

  • 避免使用 Access-Control-Allow-Origin: * 生产环境,应指定具体域名。
  • 敏感请求(如带 Cookie)需设置 Access-Control-Allow-Credentials: true,且客户端需启用 withCredentials
  • 防范 CSRF 攻击,即使使用 CORS。

总结[编辑 | 编辑源代码]

跨域问题的核心在于浏览器安全策略,解决方案需根据场景选择:

方法 适用场景 优点 缺点
CORS 现代浏览器,可控后端 标准化,支持所有 HTTP 方法 需后端配合
JSONP 旧浏览器,仅需 GET 简单兼容性好 不安全,仅 GET
代理服务器 无控制权的 API 完全绕过限制 增加服务器负载
WebSocket 实时通信 双向通信 协议特定

跨域问题={同源策略限制解决方案={CORS,JSONP,代理,WebSocket}