首页 > 应用开发 > Node.js > 一点也不复杂!Nginx 可以轻松搞定跨域问题
当你遇到跨域问题,不要立刻就选择复制去尝试。请详细看完这篇文章再处理 。我相信它能帮到你。
分析前准备:
前端网站地址: http://localhost:8080
服务端网址: http://localhost:59200
首先保证服务端是没有处理跨域的,其次,先用 Postman 测试服务端接口是正常的

跨域主要涉及4个响应头:
Access-Control-Allow-Origin:用于设置允许跨域请求源地址 (预检请求和正式请求在跨域时候都会验证)
Access-Control-Allow-Headers:跨域允许携带的特殊头信息字段 (只在预检请求验证)
Access-Control-Allow-Methods:跨域允许的请求方法或者说HTTP动词 (只在预检请求验证)

server {
listen 22222;
server_name localhost;
location / {
proxy_pass http://localhost:59200;
}
}

Access to XMLHttpRequest at 'http://localhost:22222/api/Login/TestGet' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
proxy_pass http://localhost:59200;
}
}

不过我们的配置没什么问题,问题在Nginx

server {listen 22222;server_name localhost;location / {add_header Access-Control-Allow-Origin 'http://localhost:8080' always;proxy_pass http://localhost:59200;}}
Access to XMLHttpRequest at 'http://localhost:22222/api/Login/TestGet' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
if ($request_method = 'OPTIONS') {
return 204; }
proxy_pass http://localhost:59200; } }
Access to XMLHttpRequest at 'http://localhost:22222/api/Login/TestGet' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Headers 'authorization';
#为什么写在if里面而不是接着Access-Control-Allow-Origin往下写?
因为这里只有预检请求才会检查
return 204; }
proxy_pass http://localhost:59200;
}
}
此时发现报错问题又回到了情况1

官方文档是这样说的:
There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.

配置修改如下:
server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
add_header Access-Control-Allow-Headers 'authorization';
return 204;
}
proxy_pass http://localhost:59200;
}
}
此时改完发现跨域问题已经解决了,

server {
listen 22222;
server_name localhost;
location / {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
add_header Access-Control-Allow-Headers 'authorization';
return 204;
}
if ($request_method != 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
}
proxy_pass http://localhost:59200;
}
}
还没完,继续聊 ↓↓
情况4:
Access to XMLHttpRequest at 'http://localhost:22222/api/Login/TestGet' from origin 'http://localhost:8080' has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.

server {
listen 22222;
server_name localhost;
location / {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
add_header Access-Control-Allow-Headers 'content-type,authorization';
add_header Access-Control-Allow-Methods 'PUT';
#为这么只加在这个if中,不再下面的if也加上?因为这里只有预检请求会校验,当然你加上也没事。
return 204;
}
if ($request_method != 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
}
proxy_pass http://localhost:59200;
}
}
这里注意一下,改成PUT类型后,Access-Control-Allow-Headers请求响应头又会自动校验content-type这个请求头,和情况3是一样的,缺啥补啥就行了。如果不加上content-type,则会报如下错误。


情况5:
Access to XMLHttpRequest at 'http://localhost:22222/api/Login/TestGet' from origin 'http://localhost:8080' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, http://localhost:8080', but only one is allowed.

意思就是此刻 Access-Control-Allow-Origin 请求响应头返回了多个,而只允许有一个,这种情况当然修改配置去掉 Access-Control-Allow-Origin 这个配置就可以了,不过遇到这种情况,建议Nginx配置和服务端自己解决跨域只选其一。
if $request_method = 'OPTIONS'
这个里面的 Access-Control-Allow-Origin 可不能删除,删除!=’OPTIONS’里面的就好了,因为这里如果是预检请求直接就ruturn了,请求不会再转发到59200服务,如果也删除了,就会报和情况1一样的错误。所以为什么说要不服务端代码层面解决跨域,要不就Nginx代理解决,不要混着搞,不然不明白原理的人,网上找一段代码贴就很可能解决不了问题
再贴一份完整配置(*号根据自己‘喜好’填写):
server {
listen 22222;
server_name localhost;
location / {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials 'true';
return 204;
}
if ($request_method != 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
add_header Access-Control-Allow-Credentials 'true';
}
proxy_pass http://localhost:59200;
}
}或者:
server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials 'true';
if ($request_method = 'OPTIONS') {
return 204; }
proxy_pass http://localhost:59200;
}
}来源:cnblogs.com/fnz0/p/15803011.html
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013542/viewspace-3007662/ ,如需转载,请注明出处,否则将追究法律责任。