我有一个有趣的问题,每当我在使用PHP和php-fpm运行nginx的ubuntu服务器上的虚拟主机配置中使用add_header
时,它根本不起作用,我不知道我在做什么错误。这是我的配置文件:
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;
}
我已经尝试将标题添加到其他位置部分,但结果是相同的。
任何帮助表示赞赏!!
答案 0 :(得分:81)
我有两个问题。
一个是nginx只处理 last add_header
它会在树上找到它。因此,如果add_header
上下文中有server
,而location
嵌套上下文中有另一个add_header
,则它只会处理location
上下文中的location / {}
指令。只有最深刻的背景。
来自add_header上的NGINX文档:
可能有几个add_header指令。当且仅当在当前级别上没有定义add_header指令时,这些指令才从前一级继承。
第二个问题是我所拥有的location ~* (\.php)$
块实际上是将nginx发送到另一个index.php
块(因为它会通过php
重新发送所有请求,这实际上使得nginx处理此add_header
块)。所以,我在第一个位置指令中的index.php
指令是无用的,并且在我将所需的所有指令放在php位置指令中之后它开始工作。
最后,这是我的工作配置,允许在名为Laravel的MVC框架的上下文中使用CORS(您可以轻松地更改它以适应任何具有{{1}}作为所有请求的单个入口点的PHP框架。)< / p>
server { root /path/to/app/public; index index.php; server_name test.dev; # redirection to index.php location / { try_files $uri $uri/ /index.php?$query_string; } # 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-fpm: fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; # cors configuration # whitelist of allowed domains, via a regular expression # if ($http_origin ~* (http://localhost(:[0-9]+)?)) { if ($http_origin ~* .*) { # yeah, for local development. tailor your regex as needed set $cors "true"; } # apparently, the following three if statements create a flag for "compound conditions" if ($request_method = OPTIONS) { set $cors "${cors}options"; } if ($request_method = GET) { set $cors "${cors}get"; } if ($request_method = POST) { set $cors "${cors}post"; } # now process the flag 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 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days add_header 'Access-Control-Allow-Methods' '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-Since'; add_header 'Content-Length' 0; add_header 'Content-Type' 'text/plain charset=UTF-8'; return 204; } } error_log /var/log/nginx/test.dev.error.log; access_log /var/log/nginx/test.dev.access.log; }
答案 1 :(得分:23)
当我使用以下内容测试上述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
缺少分号(;
)
测试我喜欢使用的标题
# curl -I http://example.com
根据ngx_http_headers_module manual
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';
在http
,server
和location
的上下文中,但它只出现在server
上下文中。
答案 2 :(得分:11)
由于响应代码不在允许的范围内,我遇到了无法获取响应标头的问题,除非您指定&#34;始终&#34;标题值后的关键字。
如果响应代码等于200,201,204,206,301,302,303,304,307或308,则将指定字段添加到响应头。该值可以包含变量。
答案 3 :(得分:4)
首先,让我说在浏览网页后,我发现这个答案随处可见:
location ~* \.(eot|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
}
但是,我已经决定用一个单独的答案回答这个问题,因为我只是在花了大约十个小时寻找解决方案之后才设法使这个特定的解决方案工作。
默认情况下,Nginx似乎没有定义任何[正确]字体MIME类型。通过关注this 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
文件。如上所述,上述解决方案随后起作用。显然,这个答案的目的是共享字体,但值得注意的是,Nginx中可能没有定义MIME类型。
答案 4 :(得分:1)
显然,add_header继承quirk / gotcha也适用于上游层。
我有一个脚本预先授权了另一个服务的请求,因此返回了其他服务的所有标头。
我开始添加&#39; Access-Control-Allow-Origin&#39;与这些中继标题一起输入,浏览器实际上会获得该条目并允许该请求。
答案 5 :(得分:0)
你的nginx错误日志说了什么?
您知道哪些add_header行正在破坏配置吗?如果没有,请将它们全部注释掉,然后逐个启用它们,重新加载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_header
中的两个location ~* \...
行:
add_header Pragma '';
add_header Cache-Control 'public, max-age=31536000'
您是否有理由在此处使用gzip配置,而不是在全局nginx.conf中?
答案 6 :(得分:0)
我认为通过重新加载==> nginx -s reload无法正常工作
当我使用add_header然后重新加载时,响应没有任何变化。 但是,当我故意出错并在客户端看到404错误时, 然后修复了我故意的错误并重新加载,Add_header起作用了。
答案 7 :(得分:-3)
事实证明,尝试将nginx更新到最新版本导致了这一点。我曾尝试重新安装,似乎正确地重新安装它,但实际上Ubuntu没有正确删除nginx。所以我所要做的就是重新安装Ubuntu服务器并使用标准的ubuntu存储库重新安装所有内容。