跨域(Cross-Origin)是指在浏览器中,某个网页从一个域(协议、域名、端口)向另一个域发起请求的行为。由于安全原因,浏览器会限制这种跨域请求,称为 同源策略(Same-Origin Policy)。
解决方案
代理服务器
使用服务器端代理来转发请求,避免浏览器的跨域限制。
// 前端请求本地服务器
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// 服务器端代理请求
const express = require('express');
const request = require('request');
const app = express();
app.get('/api/data', (req, res) => {
request('https://api.example.com/data', (error, response, body) => {
if (!error && response.statusCode == 200) {
res.send(body);
} else {
res.status(response.statusCode).send(error);
}
});
});
app.listen(3000, () => console.log('Server running on port 3000'));
CORS (Cross-Origin Resource Sharing)
服务器在响应头中设置 Access-Control-Allow-Origin 来允许跨域请求。
支持 GET、POST、PUT、DELETE 等多种请求方法。
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
详见 HTTP 的 CORS 词条。
JSONP (JSON with Padding)
通过 <script> 标签进行跨域请求,只支持 GET 请求。
服务器返回一个包含回调函数的 JavaScript 脚本。
<script>
function handleResponse(data) {
console.log(data);
}
</script>
<script src="https://api.example.com/data?callback=handleResponse"></script>
使用 postMessage
通过 postMessage 方法在不同窗口或 iframe 之间传递消息。
// 父窗口
const iframe = document.getElementById('myIframe');
iframe.contentWindow.postMessage('Hello from parent', 'https://example.com');
// 子窗口
window.addEventListener('message', (event) => {
if (event.origin === 'https://parent.com') {
console.log(event.data);
}
});
参考资料
禹神:一小时彻底搞懂跨域&解决方案
https://www.bilibili.com/video/BV1pT421k7yz/