跨域是指浏览器为了安全考虑,限制从一个源(协议、域名、端口)加载的文档或脚本如何与来自另一个源的资源进行交互。如果一个请求的源和当前页面的源不同,浏览器就会阻止这个请求,这就是所谓的“同源策略”。
假设我们有两个域名:
example.com
sub.example.com
尽管它们属于同一个顶级域名(example.com
),但由于二级域名不同,浏览器会认为它们是不同的源。
当你在 sub.example.com
上的页面尝试访问 example.com
上的资源时,浏览器会阻止这个请求,因为它们属于不同的源。这会导致跨域问题。
CORS 是一种机制,它使用额外的 HTTP 头来告诉浏览器,允许在一个域名的网页应用访问另一个域名下的资源。
服务器端设置示例(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-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
app.get('/data', (req, res) => {
res.json({ message: 'This is data from example.com' });
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
参考链接:
JSONP 是一种通过 <script>
标签绕过同源策略的方法。它利用了 <script>
标签没有跨域限制的特性。
客户端示例:
<!DOCTYPE html>
<html>
<head>
<title>JSONP Example</title>
</head>
<body>
<script>
function handleResponse(data) {
console.log(data);
}
</script>
<script src="http://example.com/data?callback=handleResponse"></script>
</body>
</html>
服务器端示例(Node.js + Express):
const express = require('express');
const app = express();
app.get('/data', (req, res) => {
const callback = req.query.callback;
const data = { message: 'This is data from example.com' };
res.send(`${callback}(${JSON.stringify(data)})`);
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
参考链接:
通过设置一个代理服务器,将跨域请求转发到目标服务器,从而绕过浏览器的同源策略。
客户端示例:
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data));
服务器端示例(Node.js + Express + http-proxy-middleware):
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/api', createProxyMiddleware({
target: 'http://example.com',
changeOrigin: true
}));
app.listen(3000, () => {
console.log('Proxy server running on port 3000');
});
参考链接:
跨域问题常见于以下场景:
二级域名不同会导致跨域问题,解决跨域问题的方法包括 CORS、JSONP 和代理服务器。选择哪种方法取决于具体的应用场景和需求。