• Nginx转发前后端分离跨域引发的问题-转发请求header头中含有下划线,无法转发取值


    一、起因查找

    今天发现有个前后端分离站点通过nginx转发原以为是普通的跨域问题,就简单的在配置里加上了

           location /API {
           add_header Access-Control-Allow-Origin *;
           add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,_tag_,';
           add_header Access-Control-Allow-Methods GET,POST,OPTIONS,HEAD,PUT;
           add_header Access-Control-Allow-Credentials true;
      
           proxy_set_header x-real-ip $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
    	   if ( $request_method = 'OPTIONS' ) { 
    		     return 200;
    		}
          proxy_pass http://66.66.66.66:8888/API;
    
          
        }
    

    修改完发现无效果,遂去检查一下后端的跨域配置,也无果

    二、原因分析

    查了一下发现是nginx在代理转发默认会把header头中的参数带有下划线:_ 的自定义字段省略掉,所以后端就获取不到带下划线:_ 的自定义参数名,我这里传的参数这好歹下划线

    看一下ng的官网对于客户端请求标头字段中启用或禁用下划线的说明 http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers

    机翻一下

    大体意思是默认的情况下会忽略掉带下划线的变量。要解决这个需要配置 underscores_in_headers off 改为 on

    我们在继续查看一下ng的源码,https://trac.nginx.org/nginx/browser/nginx/src/http/ngx_http_parse.c

    在ngx_http_parse_header_line() 的函数下面是这样的

    ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,ngx_uint_t allow_underscores)
    
    if (ch == '_') {
        if (allow_underscores) {
            hash = ngx_hash(0, ch);
            r->lowcase_header[0] = ch;
            i = 1;
        } else {
            r->invalid_header = 1;
        }
         break;
    }
    
    

    也可以发现其中allow_underscores 是否允许下划线这个选项

    so

    三、解决方案

    在前后端nginx配置中添加

    underscores_in_headers on;
    

    nginx配置

    server
    {
        listen 80;
        server_name api.2021.com;
    
        underscores_in_headers on;   #这里添加
    
        #REWRITE-END
        location / {
    
         proxy_pass http://66.66.66.66:8888;
        
        }
    
        #禁止访问的文件或目录
        location ~ ^/(.user.ini|.htaccess|.git|.svn|.project|LICENSE|README.md)
        {
            return 404;
        }
        
    
        access_log  /usr/local/nginx/logs/api.2021.com.log;
        error_log  /usr/local/nginx/logs/api.2021.com.error.log;
    }
    

    就OK了

  • 相关阅读:
    Linux 配置 SSL 证书
    freemarker 异常处理
    StringTemplateLoader的用法
    序列的重点知识小结
    Linux下安装lrzsz上传下载工具
    ajax技术
    Response对象介绍(服务器到客户端)
    Request对象介绍(客户端到服务器)
    JSP--内置对象&动作标签介绍
    JSP--常用指令
  • 原文地址:https://www.cnblogs.com/shook/p/14277574.html
Copyright © 2020-2023  润新知