1、什么是跨域
跨域是指一个域名下的资源去访问另一个域名下的资源。
2、什么是同源策略
同源策略是浏览器的一种安全机制,它要求发送请求的URL与服务器返回的URL必须具有相同的协议、主机和端口。
3、如何解决跨域问题
通过 Nginx 反向代理可以解决跨域问题,通常涉及设置 CORS 相关的响应头。以下是一个典型的 Nginx 配置示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| location /myProject/api/ {
if ($request_method = 'OPTIONS') { return 204; }
add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Credentials' 'false' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
proxy_pass http://localhost:9001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; if ($http_origin = "") { return; }
if ($http_origin !~* "(http://www.test.com|http://10.14.32.138)") { return 403; } }
|
解释:
Access-Control-Allow-Origin: 允许指定的域名进行跨域访问。通常通过 $http_origin 来动态获取请求头中的 Origin,或者直接指定具体的域名(如http://www.test.com)。
Access-Control-Allow-Credentials: 设置为 false 时,不允许发送 cookies 等凭证信息。
Access-Control-Allow-Methods: 指定允许的 HTTP 方法,如 GET, POST, OPTIONS。
Access-Control-Allow-Headers: 指定允许的请求头,通常包括 Authorization, Content-Type 等常见头信息。
4、跨域常见场景
4.1 不同域名
- example.com 访问 api.example.com
- a.com 访问 b.com
4.2 不同端口
- localhost:8080 访问 localhost:3000
4.3 不同协议
5.1 CORS(跨域资源共享)
CORS(Cross-Origin Resource Sharing)是一种允许浏览器向跨源服务器发出请求的机制。除了在 Nginx 中配置跨域,还可以在后端应用中设置 CORS 响应头,以控制跨域请求。
例如,在一个 Node.js 应用中,可以使用如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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, OPTIONS"); res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization"); next(); });
app.get('/api/data', (req, res) => { res.json({ message: "Hello, world!" }); });
app.listen(3000, () => console.log("Server is running on port 3000"));
|
在这个例子中,CORS 头部通过 res.header() 设置,允许所有域名(*)进行跨域访问,支持 GET, POST, PUT 等 HTTP 方法,并指定允许的请求头。
5.2 JSONP(JSON with Padding)
JSONP 是一种通过 <script> 标签来绕过同源策略进行跨域请求的方法。它的原理是利用 <script> 标签可以跨域加载 JavaScript 资源的特点,通过回调函数的方式返回数据。JSONP 只支持 GET 请求。
1 2 3 4 5 6 7 8 9
| <script type="text/javascript"> function handleResponse(data) { console.log(data); }
var script = document.createElement('script'); script.src = 'http://example.com/api?callback=handleResponse'; document.body.appendChild(script); </script>
|
5.3 WebSocket
WebSocket 允许在浏览器与服务器之间建立持久化的双向连接,这使得 WebSocket 成为一种天然的跨域解决方案。通过 WebSocket 协议,浏览器与不同域的服务器之间可以实时通信,且不受同源策略的限制。
5.4 后端代理
通过配置服务器端反向代理,将跨域请求转发到目标服务器。Nginx 和其他反向代理服务器可以帮助解决跨域问题。例如:
1 2 3 4 5 6
| location /api/ { proxy_pass http://api.example.com; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
|
在这个例子中,Nginx 会将 /api/ 开头的请求转发到 http://api.example.com,避免了跨域问题。