跨域问题是现代 Web 开发中常见的挑战,主要源于浏览器的同源策略(Same-Origin Policy)。这一策略限制了从一个源(域名、协议、端口)加载的文档或脚本与不同源的资源进行交互,以防止恶意操作。
一、同源策略
同源策略定义了“源”的概念,即协议、域名和端口三者相同才算同源。比如:
https://example.com:443/page
和 https://example.com/page
同源。
https://example.com
和 http://example.com
不同源。
https://example.com
和 https://api.example.com
不同源。
二、跨域的主要场景
- AJAX 请求:通过 JavaScript 发起的网络请求。
- Web 字体:加载不同源的字体文件。
- iframe:嵌入不同源的网页。
三、解决跨域问题的方法
- CORS(跨源资源共享):
通过设置 HTTP 头部,允许特定源访问资源。
示例:
Access-Control-Allow-Origin: https://your-frontend.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
优点:支持多种请求方式,安全性高,适用于大多数现代浏览器。
- JSONP(JSON with Padding):
通过
function callback(data) {
console.log(data);
}
const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=callback';
document.body.appendChild(script);
缺点:只支持 GET 请求,存在安全隐患。
- 代理服务器:
在同源的服务器上创建一个中转接口,前端请求该接口,由它去请求目标资源。
示例:使用 Webpack 的 devServer 代理配置。
devServer: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
},
},
}
优点:简化了跨域请求的复杂性,适用于开发阶段。
- WebSocket:
WebSocket 允许跨域通信,不受同源策略限制,适合实时应用。
const socket = new WebSocket('wss://api.example.com/socket');
socket.onmessage = function(event) {
console.log(event.data);
};
缺点:需要服务器支持 WebSocket。
- 修改浏览器设置:
在开发过程中,可以通过启动参数禁用同源策略,例如使用 Chrome 的 --disable-web-security 选项。
缺点:不适合生产环境,容易引发安全问题。
四、注意事项
- 安全性:选择解决方案时,确保不引入安全漏洞,尤其是 JSONP。
- 性能:考虑网络延迟和资源加载速度,适当使用缓存策略。
- 兼容性:不同浏览器对 CORS 的支持程度有所不同,需测试兼容性。