🚀 前端跨域分享
📌 目录
章节 | 内容概述 |
---|---|
[1. 什么是跨域](#章节 内容概述 1. 什么是跨域 跨域定义、同源策略详解 2. 为什么需要跨域解决方案 现代Web应用需求分析 3. 跨域解决方案 7种主流方案对比 4. 开发注意事项 安全、性能与调试指南 "#1-%E4%BB%80%E4%B9%88%E6%98%AF%E8%B7%A8%E5%9F%9F") | 跨域定义、同源策略详解 |
[2. 为什么需要跨域解决方案](#章节 内容概述 1. 什么是跨域 跨域定义、同源策略详解 2. 为什么需要跨域解决方案 现代Web应用需求分析 3. 跨域解决方案 7种主流方案对比 4. 开发注意事项 安全、性能与调试指南 "#2-%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81%E8%B7%A8%E5%9F%9F%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88") | 现代Web应用需求分析 |
[3. 跨域解决方案](#章节 内容概述 1. 什么是跨域 跨域定义、同源策略详解 2. 为什么需要跨域解决方案 现代Web应用需求分析 3. 跨域解决方案 7种主流方案对比 4. 开发注意事项 安全、性能与调试指南 "#3-%E8%B7%A8%E5%9F%9F%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88") | 7种主流方案对比 |
[4. 开发注意事项](#章节 内容概述 1. 什么是跨域 跨域定义、同源策略详解 2. 为什么需要跨域解决方案 现代Web应用需求分析 3. 跨域解决方案 7种主流方案对比 4. 开发注意事项 安全、性能与调试指南 "#4-%E5%BC%80%E5%8F%91%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9") | 安全、性能与调试指南 |
1. 什么是跨域
🔍 核心概念
定义:跨域是指浏览器出于安全考虑,限制网页脚本访问不同源(协议+域名+端口)的资源。
同源策略(Same-origin policy):
- 浏览器核心安全机制
- 限制不同源的脚本交互
- 影响范围:DOM访问、AJAX请求、Cookie/Storage读取等
1.1 什么是同源
同源定义: 两个URL被认为是同源当且仅当它们的协议、域名和端口完全相同。
判断规则:
- 协议相同(http/https)
- 域名相同(example.com)
- 端口相同(80/443)
示例:
- 同源:example.com/page1 和 example.com/page2
- 不同源:example.com 和 example.com(协议不同)
- 不同源:example.com 和 sub.example.com(域名不同)
- 不同源:example.com:80 和 example.com:8080(端口不同)
2. 为什么需要跨域解决方案
💡 背景需求
- 现代Web应用需要整合多服务
- 微服务架构下前后端分离
- 第三方API调用需求
3. 跨域解决方案
🛠 技术选型
🔹 3.1 JSONP
⭐ 适用场景: 简单GET请求跨域
原理 :利用<script>
标签没有跨域限制的特性,通过动态创建script标签来获取数据。
实现步骤:
- 前端定义回调函数
javascript
function handleResponse(data) {
console.log('Received:', data);
}
- 动态创建script标签
javascript
const script = document.createElement('script');
script.src = 'http://example.com/api?callback=handleResponse';
document.body.appendChild(script);
- 服务器返回数据并调用回调函数
javascript
// 服务器响应
handleResponse({"data": "value"});
注意事项:
- 只支持GET请求
- 安全性较低,容易受到XSS攻击
- 需要服务器端配合
🔹 3.2 CORS (跨源资源共享)
⭐ 适用场景: 现代浏览器标准跨域方案
原理:CORS(跨源资源共享)是一种现代的跨域解决方案,它通过在HTTP响应头中添加特定的字段,来告诉浏览器哪些源站有权限访问服务器上的资源。当浏览器发起跨域请求时,会根据服务器返回的响应头信息来决定是否允许该请求。这样可以在保证安全性的前提下,实现跨域资源的共享。
请求类型:
- 简单请求:当请求满足一定条件(如使用GET、POST或HEAD方法,请求头只包含特定的字段等)时,浏览器会直接发送实际请求,不会进行预检。
- 预检请求:对于不满足简单请求条件的请求,浏览器会先发送一个OPTIONS请求到服务器,询问服务器是否允许该跨域请求。只有在服务器返回允许的响应后,浏览器才会发送实际请求。
实现步骤:
- 服务器设置响应头
http
# 允许指定的源站访问资源
Access-Control-Allow-Origin: http://example.com
# 允许的请求方法
Access-Control-Allow-Methods: GET, POST, PUT
# 允许的请求头
Access-Control-Allow-Headers: Content-Type
# 允许携带凭证(如cookie)进行跨域请求
Access-Control-Allow-Credentials: true
- 前端发起跨域请求
javascript
// 使用fetch API发起跨域请求
fetch('http://api.example.com/data', {
method: 'GET',
// 设置为 include 表示携带凭证(如cookie)进行请求
credentials: 'include'
}) // 获取响应并将其解析为JSON格式
.then(response => response.json())
注意事项:
- 需区分简单请求和预检请求,不同类型的请求处理方式不同。
- 生产环境应严格限制允许的源站,避免安全风险。
- 携带凭证时Access-Control-Allow-Origin不能为*,必须指定具体的源站。
- 预检请求会增加一次HTTP请求开销,应尽量减少不必要的预检请求。
🔹 3.3 Node代理
⭐ 适用场景: 开发环境代理解决方案
原理:通过Node.js服务器作为中间层,转发请求到目标服务器。
实现步骤:
- 创建Express服务器
javascript
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/api', createProxyMiddleware({
target: 'http://target-server.com',
changeOrigin: true
}));
app.listen(3000);
- 前端请求本地代理
javascript
fetch('http://localhost:3000/api/data')
.then(response => response.json())
.then(data => console.log(data));
注意事项:
- 需要额外维护代理服务器
- 可以添加认证和日志功能
🔹 3.4 Nginx反向代理
⭐ 适用场景: 生产环境高性能代理
原理:通过Nginx配置反向代理,将请求转发到目标服务器。
实现步骤:
- Nginx配置示例
nginx
server {
listen 80;
server_name yourdomain.com;
location /api/ {
proxy_pass http://target-server.com/;
proxy_set_header Host $host;
}
}
- 前端请求Nginx服务器
javascript
fetch('http://yourdomain.com/api/data')
.then(response => response.json())
.then(data => console.log(data));
注意事项:
- 高性能,适合生产环境
- 需要服务器运维知识
🔹 3.5 WebSocket
⭐ 适用场景: 实时双向通信
原理:WebSocket协议本身支持跨域,通过建立长连接实现跨域通信。
实现步骤:
- 服务器实现WebSocket服务
javascript
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', ws => {
ws.on('message', message => {
console.log('Received:', message);
ws.send('Server response');
});
});
- 前端建立连接
javascript
const socket = new WebSocket('ws://example.com:8080');
socket.onopen = () => {
socket.send('Hello Server!');
};
socket.onmessage = (event) => {
console.log('Message from server:', event.data);
};
注意事项:
- 适合实时通信场景
- 需要服务器端支持
🔹 3.6 postMessage
⭐ 适用场景: iframe间通信
原理:通过window.postMessage()方法实现跨窗口通信。
实现步骤:
- 父窗口发送消息
javascript
const iframe = document.getElementById('my-iframe');
iframe.contentWindow.postMessage('Hello', 'http://child-domain.com');
- iframe接收消息
javascript
window.addEventListener('message', (event) => {
if (event.origin !== 'http://parent-domain.com') return;
console.log('Received:', event.data);
event.source.postMessage('Response', event.origin);
});
注意事项:
- 需要验证origin确保安全
- 适合iframe间通信
🔹 3.7 document.domain + iframe
⭐ 适用场景: 同主域子域间通信
原理:通过设置相同的主域,实现跨子域通信。
实现步骤:
- 主页面设置
javascript
document.domain = 'example.com';
- iframe页面设置
javascript
document.domain = 'example.com';
- 通过iframe的contentWindow进行通信
javascript
const iframe = document.getElementById('my-iframe');
iframe.contentWindow.someFunction();
注意事项:
- 仅适用于同主域下的子域
- 现代浏览器限制较多
4. 开发注意事项
⚠ 重要提示
-
安全性:
- 严格验证跨域请求来源
- 避免敏感数据暴露
- 防范CSRF/XSS攻击
-
性能优化:
- 减少不必要的预检请求
- 合理设置缓存头
- 考虑CDN加速
-
调试技巧:
- 使用浏览器开发者工具
- 查看网络请求头
- 模拟不同域环境测试
-
生产部署:
- 配置HTTPS证书
- 设置合理的CORS头
- 监控跨域请求错误