nginx的add_header不工作

我有一个有趣的问题,每当我在虚拟主机configuration中使用add_header运行nginx的PHP和PHP- add_header的Ubuntu服务器,它根本不工作,我不知道我在做什么错了。 这是我的configuration文件:

 server { listen 80; ## listen for ipv4; this line is default and implied #listen [::]:80 default ipv6only=on; ## listen for ipv6 root /var/www/example.com/webroot/; index index.html index.htm index.php; # Make site accessible from http://www.example.com/ server_name www.example.com; # max request size client_max_body_size 20m; # enable gzip compression gzip on; gzip_static on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript; add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header PS 1 location / { # First attempt to serve request as file, then # as directory, then fall back to index.html try_files $uri $uri/ /index.php?$query_string; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules } location ~* \.(css|js|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|$ # 1 year -> 31536000 expires 500s; access_log off; log_not_found off; add_header Pragma public; add_header Cache-Control "max-age=31536000, public"; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini # With php5-cgi alone: #fastcgi_pass 127.0.0.1:9000; # With php5-fpm: fastcgi_pass unix:/var/run/example.sock; fastcgi_index index.php?$query_string; include fastcgi_params; # instead I want to get the value from Origin request header } # Deny access to hidden files location ~ /\. { deny all; access_log off; log_not_found off; } error_page 403 /403/; } server { listen 80; server_name example.com; rewrite ^ http://www.example.com$request_uri? permanent; } 

我已经尝试将标题添加到其他位置部分,但结果是相同的。

任何帮助赞赏!

有两个问题给我。

一个是,nginx只处理最后一个 add_header它在树上点击。 所以如果你在server上下文中有一个add_header ,那么在location嵌套上下文中的另一个,它只会处理location上下文中的add_header指令。 只有最深的背景。

来自add_header上的NGINX文档:

可能有几个add_header指令。 当且仅当在当前级别上没有定义add_header指令时,这些指令才从前一级inheritance。

第二个问题是,我location / {}块实际上是将nginx发送到其他location ~* (\.php)$ block(因为它会通过index.php重新发送所有请求,并且实际上使得nginx进程php块)。 所以,我的add_header指令在第一个位置指令内是无用的,并且在我将所需的所有指令放在php位置指令中后,它开始工作。

最后,这里是我的工作configuration,允许CORS在名为Laravel的MVC框架的上下文中(您可以轻松地更改它以适应任何具有index.php作为所有请求的单一入口点的PHP框架)。

服务器{
     root / path / to / app / public;
     index index.php;

     server_name test.dev;

     #redirect到index.php
    位置 / {
         try_files $ uri $ uri / /index.php?$query_string;
     }

     #将PHP脚本传递给在127.0.0.1:9000上监听的FastCGI服务器
    位置〜\ .php $ {
         fastcgi_split_path_info ^(。+ \。php)(/.+)$;
         #注意:你应该有“cgi.fix_pathinfo = 0;” 在php.ini中

         #使用php5-fpm:
         fastcgi_pass unix:/var/run/php5-fpm.sock;
         fastcgi_index index.php;
        包括fastcgi_params;

         #corsconfiguration
         #允许的域的白名单,通过正则expression式
         #if($ http_origin〜*(http:// localhost(:[0-9] +)?)){
        如果($ http_origin〜*。*){#是的,为本地开发。 根据需要定制您的正则expression式
             设置$ cors“true”;
         }

         #显然,以下三条if语句为“复合条件”创build了一个标志,
         if($ request_method = OPTIONS){
            设置$ cors“$ {cors}选项”;
         }

         if($ request_method = GET){
            设置$ cors“$ {cors} get”;
         }

         if($ request_method = POST){
            设置$ cors“$ {cors} post”;
         }

         #现在处理标志
         if($ cors ='trueget'){
             add_header'Access-Control-Allow-Origin'“$ http_origin”;
             add_header'Access-Control-Allow-Credentials''true';
         }

         if($ cors ='truepost'){
             add_header'Access-Control-Allow-Origin'“$ http_origin”;
             add_header'Access-Control-Allow-Credentials''true';
         }

         if($ cors ='trueoptions'){
             add_header'Access-Control-Allow-Origin'“$ http_origin”;
             add_header'Access-Control-Allow-Credentials''true';

             add_header'访问控制最大年龄'1728000;  #caching20天的预检值
             add_header'访问控制允许方法''GET,POST,OPTIONS';
             add_header'Access-Control-Allow-Headers''Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified -以来';

             add_header'Content-Length'0;
             add_header'Content-Type''text / plain charset = UTF-8';
            返回204;
         }
     }

     error_log /var/log/nginx/test.dev.error.log;
     access_log /var/log/nginx/test.dev.access.log;
 }

上述要点在: https : //gist.github.com/adityamenon/6753574

当我testing上面的add_header设置:

 # nginx -t && service nginx reload 

我明白了

 nginx: [emerg] directive "add_header" is not terminated by ";" in /etc/nginx/enabled-sites/example.com.conf:21 nginx: configuration file /etc/nginx/nginx.conf test failed 

所以抱怨是不屑一顾的:

 add_header PS 1 

错过了分号( ;

testing我喜欢使用的标题

 # curl -I http://example.com 

根据ngx_http_headers_module手册

 syntax: add_header name value; default: — context: http, server, location, if in location 

我进一步尝试

 add_header X-test-A 1; add_header "X-test-B" "2"; add_header 'X-test-C' '3'; 

httpserverlocation的上下文中,但它只出现在server上下文中。

由于响应代码不在允许的范围内,所以我没有得到响应头的问题,除非在标头值之后指定了“always”关键字。

从官方文档:

如果响应代码等于200,201,204,206,301,302,303,304,307或308,则将指定的字段添加到响应头中。该值可以包含variables。

首先,让我说,在环顾networking之后,我发现这个答案到处涌现:

location ~* \.(eot|ttf|woff|woff2)$ { add_header Access-Control-Allow-Origin *; }

不过,我决定用一个单独的答案来回答这个问题,因为我只花了十多个小时寻找解决scheme后才设法使这个特定的解决scheme工作。

看来,Nginx默认没有定义任何[正确的]字体MIMEtypes。 按照这个tuorial我发现我可以添加以下内容:

application/x-font-ttf ttc ttf; application/x-font-otf otf; application/font-woff woff; application/font-woff2 woff2; application/vnd.ms-fontobject eot;

到我的etc/nginx/mime.types文件。 如上所述,上述解决scheme然后工作。 显然,这个答案的目的是共享字体,但值得注意的是,在Nginx中可能没有定义MIMEtypes。

事实certificate,试图更新nginx到最新版本造成了这一点。 我曾尝试以前重新安装,似乎正确地重新安装,但实际上Ubuntu没有正确删除nginx。 所以我所要做的就是重新安装Ubuntu服务器,并使用标准的ubuntu存储库重新安装所有的东西。

你的nginx错误日志说什么?

你知道哪些add_header行破坏了configuration吗? 如果不是,请全部注释掉,然后一个一个地启用它们,然后重新加载nginx来查看哪一个是问题。 我会从评论区块开始:

 add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header PS 1 

问题可能是你正在设置核心httpHeaders模块不支持的标头。 安装NginxHttpHeadersMoreModule可能会有帮助。

另外,尝试用以下add_headerreplacelocation ~* \...的两个add_header行:

 add_header Pragma ''; add_header Cache-Control 'public, max-age=31536000' 

是否有一个原因,你在这里的gzipconfiguration,而不是在你的全局nginx.conf?

显然,add_header的inheritance怪癖/ gotcha也适用于上游层。

我有一个脚本预先授权用于其他服务的请求,因此返回来自其他服务的所有标头。

一旦我开始添加一个“Access-Control-Allow-Origin”条目以及这些中继头文件,浏览器实际上就会获得条目并允许请求。