CORS 跨域 POST 请求会出 OPTION 与请求,导致 2 次请求该如何优化?

2021-07-28 11:15:06 +08:00
 stille

前端 POST json 格式提交会发 OPTION 预请求,返回 200,在发主请求,导致后端收到两次请求.

于是在 nginx 里配置如下:

    if ($request_method = 'OPTIONS') {
        proxy_pass http://127.0.0.1:33333;
    }

	proxy_pass http://127.0.0.1:44444;
    

第一次 OPTION 请求发给另外一个端口 33333,第二次请求发送给真正的后端 44444 ,是可以解决这个问题.

但是 33333 这个端口要是 502 404 等错误,也会导致第二次请求发不出去..而且这么搞感觉也不优雅...

在无法修改后端的情况下,还有什么方法能优化?

2967 次点击
所在节点    NGINX
18 条回复
Terry05
2021-07-28 11:17:28 +08:00
我村的做法是检查到 methods = 'OPTIONS' 直接返回 204 状态
TsubasaHanekaw
2021-07-28 11:17:45 +08:00
你都能改 nginx 了 为什么还要走 cors 跨域呢.
creanme
2021-07-28 11:19:09 +08:00
直接把前端请求转发到后端地址?这样就不会出现跨域了。
TsubasaHanekaw
2021-07-28 11:20:41 +08:00
直接 nginx 就能返回 200
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
return 200;
}
sanmaozhao
2021-07-28 11:20:42 +08:00
直接返回内容就行了啊,不用再转发给后端了。比如:

add_header 'Access-Control-Allow-Origin' '*';
add_header 'Content-Length' 0;
return 204;

或者用这个思路:
既然都有 nginx 了,不能把前端页面和转发的后端请求都放进来么?这样就不跨域了
NjcyNzMzNDQ3
2021-07-28 11:21:45 +08:00
按#1 的方法做就行,option 只是测试跨域的

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

if ($request_method = 'OPTIONS') {
return 204;
}
stille
2021-07-28 11:23:41 +08:00
@Terry05 @sanmaozhao @NjcyNzMzNDQ3 @TsubasaHanekaw

谢谢各位,刚发完贴我就想到这种直接 return 形式...果然..我去试试
stille
2021-07-28 11:24:10 +08:00
@creanme
@TsubasaHanekaw

特殊情况,前后端不再一起也用的不同域名.
also24
2021-07-28 11:31:43 +08:00
哈哈哈哈楼主这个提问,让我想起了 @mitu9527 的这个旧贴 https://www.v2ex.com/t/703603
scemsjyd
2021-07-28 11:31:45 +08:00
OPTION 响应 Header 中通过下面这个属性控制 OPTION 请求的缓存时间
Access-Control-Max-Age: 7200
可以减少 OPTION 请求次数
stille
2021-07-28 11:41:16 +08:00
@scemsjyd 嗯,这个配置过了..但过期或者首次还是会有问题.
stille
2021-07-28 11:41:58 +08:00
@also24 谢谢.去看看
also24
2021-07-28 11:50:26 +08:00
@stille #12
那个主题下的回复方向相对比较散,建议先看 18# 我的回复 🙄
qwerthhusn
2021-07-28 16:00:23 +08:00
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type,Accept,Origin,User-Agent,Cache-Control,X-User-Token,X-Transaction-ID,X-Requested-With' always;
add_header 'Access-Control-Allow-Methods' '*' always;
add_header 'Access-Control-Max-Age' '3600' always;

if ($request_method = 'OPTIONS') {
return 204;
}


1. Access-Control-Allow-Headers,如果你们的工程有自定义的头,需要加进去
2. Access-Control-Max-Age 要设置有效时间,浏览器会记录此时间,在此时间内此域名不再发送 options 请求,不然每次请求都会重新发一次 OPTIONS
stille
2021-07-29 15:21:02 +08:00
@qwerthhusn 奇怪了

add_header 'Access-Control-Max-Age' '3600' always;

设置了,但是每次请求还是有预请求
qwerthhusn
2021-07-29 16:25:02 +08:00
@stille 如果用的 F12 看的,先把 Disable Cache 不要勾选。让浏览器走缓存
ch2
2021-07-29 18:00:56 +08:00
OPTION 只要是跨域请求都会自动发的,这个是浏览器的机制
vance123
2022-04-08 14:56:20 +08:00
@qwerthhusn 纠正下,Access-Control-Max-Age 仅对单个资源也就是 url 有效,不同的 url 会发起新的 preflight 请求。

https://stackoverflow.com/questions/42131714/cors-access-control-max-age-works-for-same-origin-or-just-same-request-url

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/792223

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX