CORS 跨域 POST 请求会出 OPTION 与请求,导致 2 次请求该如何优化? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
stille
V2EX    NGINX

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

  •  
  •   stille
    stilleshan 2021-07-28 11:15:06 +08:00 3353 次点击
    这是一个创建于 1610 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前端 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 等错误,也会导致第二次请求发不出去..而且这么搞感觉也不优雅...

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

    18 条回复    2022-04-08 14:56:20 +08:00
    Terry05
        1
    Terry05  
       2021-07-28 11:17:28 +08:00
    我村的做法是检查到 methods = 'OPTIONS' 直接返回 204 状态
    TsubasaHanekaw
        2
    TsubasaHanekaw  
       2021-07-28 11:17:45 +08:00   1
    你都能改 nginx 了 为什么还要走 cors 跨域呢.
    creanme
        3
    creanme  
       2021-07-28 11:19:09 +08:00
    直接把前端请求转发到后端地址?这样就不会出现跨域了。
    TsubasaHanekaw
        4
    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
        5
    sanmaozhao  
       2021-07-28 11:20:42 +08:00
    直接返回内容就行了啊,不用再转发给后端了。比如:

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

    或者用这个思路:
    既然都有 nginx 了,不能把前端页面和转发的后端请求都放进来么?这样就不跨域了
    NjcyNzMzNDQ3
        6
    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
        7
    stille  
    OP
       2021-07-28 11:23:41 +08:00
    @Terry05 @sanmaozhao @NjcyNzMzNDQ3 @TsubasaHanekaw

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

    特殊情况,前后端不再一起也用的不同域名.
    also24
        9
    also24  
       2021-07-28 11:31:43 +08:00
    哈哈哈哈楼主这个提问,让我想起了 @mitu9527 的这个旧贴 t/703603
    scemsjyd
        10
    scemsjyd  
       2021-07-28 11:31:45 +08:00
    OPTION 响应 Header 中通过下面这个属性控制 OPTION 请求的缓存时间
    Access-Control-Max-Age: 7200
    可以减少 OPTION 请求次数
    stille
        11
    stille  
    OP
       2021-07-28 11:41:16 +08:00
    @scemsjyd 嗯,这个配置过了..但过期或者首次还是会有问题.
    stille
        12
    stille  
    OP
       2021-07-28 11:41:58 +08:00
    @also24 谢谢.去看看
    also24
        13
    also24  
       2021-07-28 11:50:26 +08:00
    @stille #12
    那个主题下的回复方向相对比较散,建议先看 18# 我的回复
    qwerthhusn
        14
    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
        15
    stille  
    OP
       2021-07-29 15:21:02 +08:00
    @qwerthhusn 奇怪了

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

    设置了,但是每次请求还是有预请求
    qwerthhusn
        16
    qwerthhusn  
       2021-07-29 16:25:02 +08:00
    @stille 如果用的 F12 看的,先把 Disable Cache 不要勾选。让浏览器走缓存
    ch2
        17
    ch2  
       2021-07-29 18:00:56 +08:00
    OPTION 只要是跨域请求都会自动发的,这个是浏览器的机制
    vance123
        18
    vance123  
       2022-04-08 14:56:20 +08:00 via Android
    @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
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2777 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 14:59 PVG 22:59 LAX 06:59 JFK 09:59
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86