V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
dany813
V2EX  ›  NGINX

Nginx 前端配置跨域问题,麻烦老哥们指点下

  •  
  •   dany813 · 2019-08-09 15:37:05 +08:00 · 3884 次点击
    这是一个创建于 1964 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前每次都是后端 Java 老哥,配的 CORS 跨域,这次一个新项目,我看老哥还没配置跨域,就想着自己先用 Nginx 配置下 现在遇到一点问题 首先贴一下我的 Nginx 配置

       server {
            listen       8008;
            server_name  localhost;
            # 根路径指到 index.html
            location / {
                root   html;
                index  index.html index.htm;
            }
            location /df-share {
                add_header 'Access-Control-Allow-Origin' *;
                add_header 'Access-Control-Allow-Credentials' 'true';
                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';
    
    
                if ($request_method = 'OPTIONS') {
                    add_header 'Access-Control-Allow-Origin' *;
                    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
                    add_header 'Access-Control-Max-Age' 1728000;
                    add_header 'Content-Length' 0; return 200;
                    }
    
                  proxy_pass http://139.217.96.70; # 转发地址
             }
            error_page   405 =200 @405;
            location @405{
                add_header Content-Length 0;
                add_header Content-Type text/plain;
                add_header Access-Control-Allow-Headers *;
                add_header Access-Control-Allow-Methods *;
                add_header Access-Control-Allow-Origin *;
                return 200;
            }
      }
    

    前端调用的 API 地址

    http://localhost:8008
    

    现在页面上是没有跨域的显示了,但是每次请求的时候只发送了一个 OPTIONS 请求,之前正确的情况应该,先一个 OPTIONS 请求,后面跟一个正确的请求, 下面截图是发送的 OPTIONS 请求 image.png 我 Nginx 哪里配错了吗,求老哥们指导下

    16 条回复    2019-08-10 10:14:27 +08:00
    vampuke
        1
    vampuke  
       2019-08-09 15:45:33 +08:00
    跨域好像不是这么用的。。。
    dany813
        2
    dany813  
    OP
       2019-08-09 15:50:15 +08:00
    @vampuke 额 我也是第一次这样搞,那该怎么用呢
    jay4497
        3
    jay4497  
       2019-08-09 16:00:55 +08:00
    if ($request_method = 'OPTIONS') 那段多余了吧,而且还 return 了,删掉试试?
    aaahhh123
        4
    aaahhh123  
       2019-08-09 16:02:45 +08:00
    马克 下班了看
    onfuns
        5
    onfuns  
       2019-08-09 16:13:39 +08:00   ❤️ 1
    $request_method = 'OPTIONS' 这段删掉,OPTIONS 是复杂请求时的预检,检查请求头是否正确,浏览器触发,不用单独处理,除非用到 cookie 时再过滤掉就行,OPTIONS 是不带 cookie 和参数的。你这里直接 retuen 掉就出错了。
    dany813
        6
    dany813  
    OP
       2019-08-09 16:15:30 +08:00
    @jay4497 去掉就会出现跨域的问题
    dany813
        7
    dany813  
    OP
       2019-08-09 16:19:00 +08:00
    @onfuns 我现在这边是每个请求都先发一个预检,去掉的话,请求就是 403 Invalid CORS request
    jay4497
        8
    jay4497  
       2019-08-09 16:22:48 +08:00
    @dany813 只去掉 return 段呢?
    dany813
        9
    dany813  
    OP
       2019-08-09 16:32:43 +08:00
    @jay4497 还是 403 Invalid CORS request
    webfrogs
        10
    webfrogs  
       2019-08-09 16:36:41 +08:00
    改下 OPTIONS 里的 `add_header 'Access-Control-Allow-Origin' "$http_origin";` 试试呢~~
    vance
        11
    vance  
       2019-08-09 16:38:34 +08:00
    试试
    location /df-share {
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain; charset=utf-8';
    add_header 'Content-Length' 0;
    return 204;
    }

    proxy_pass http://139.217.96.70;
    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;
    proxy_connect_timeout 5;
    }
    jay4497
        12
    jay4497  
       2019-08-09 16:48:59 +08:00
    配置的这个 server 段只是个代理吧,没跑其它的话,location /df-share 段没必要,这个里边的去掉判断 OPTIONS 的那段全部移到 location / 下,我测试的是可以的。。。
    dany813
        13
    dany813  
    OP
       2019-08-09 16:50:09 +08:00
    @vance 老哥 你这个配置和我现在的配置,都能解决跨域,但是前端还是只会发送一个 option 的请求,后面那个正式的请求没有发送
    dany813
        14
    dany813  
    OP
       2019-08-09 17:01:03 +08:00
    @jay4497 好的 我去试下
    auser
        15
    auser  
       2019-08-10 00:05:31 +08:00 via iPhone
    不要在 nginx 配置中使用 if 原因见官方的文档
    因此添加响应头的代码应该放在程序代码里
    随后的跨域问题就是把几个相关的 header 加上
    具体参考见 MDN 网站相关章节
    zado
        16
    zado  
       2019-08-10 10:14:27 +08:00
    只会发送一个 option 的请求可能是 nginx 返回的 option 规则不符合接下来的请求,所以浏览器把接下来的请求屏蔽了。
    根据你下次请求的,试试改变或补充一下 option 规则。贴一下我网站上正在使用规则:
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Access-Control-Allow-Headers: Content-Type, Authorization, Accept, Range, Origin
    Access-Control-Max-Age: 864000
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5158 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 01:17 · PVG 09:17 · LAX 17:17 · JFK 20:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.