2013-08-26 58 views
38

我有一個有趣的問題,當我在使用PHP和php-fpm運行nginx的ubuntu服務器上的虛擬主機配置中使用add_header時,它根本不起作用,我不知道我在做什麼錯誤。這裏是我的配置文件:nginx 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; 
} 

我試過將標題添加到其他位置部分,但結果是相同的。

任何幫助讚賞!

+1

最後發現一個問題,其幾乎完全一樣的問題,因爲我,但沒有答案:( –

回答

-2

事實證明,試圖nginx的更新到最新的版本是造成這一點。我曾嘗試重新安裝,似乎正確地重新安裝它,但實際上Ubuntu沒有正確刪除nginx。所以我所要做的就是重新安裝Ubuntu服務器,並使用標準的ubuntu存儲庫重新安裝一切。

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?

+1

我不認爲httpHeaders是挑剔它增加了頭部。 – kravietz

22

當我測試上述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 

所以抱怨是reagarding這一行:

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 

頭我的httpserverlocation範圍內進一步嘗試

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

,但它只出現在server上下文中。

62

有兩個問題給我。

一個是nginx只處理最後的add_header它沿着一棵樹倒下。因此,如果您在server上下文中有add_header,則另一個在location嵌套上下文中,它只會在location上下文內處理add_header指令。只有最深的背景。

從NGINX文檔上add_header

可能有幾個add_header指令。當且僅當在當前級別上沒有定義add_header指令時,這些指令才從前一級繼承。

第二個問題是在location/{}塊,我在地方被實際發送nginx的其他location ~* (\.php)$塊(因爲它會通過index.php repath所有請求,這實際上使nginx的過程本php塊)。所以,我的add_header指令在第一個位置指令內是無用的,並且在我將所需的所有指令放入php location指令後開始工作。最後,這裏是我的工作配置,允許在稱爲Laravel的MVC框架的上下文中使用CORS(您可以輕鬆地將此更改爲適合任何具有index.php作爲所有請求的單個入口點的PHP框架)。

 
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; 
} 

以上部分的要點是:https://gist.github.com/adityamenon/6753574

+2

謝謝你,幫我解決我的問題。我有在nginx.conf中添加了一個頭文件,但它沒有讀取,在讀完這些之後,我將add_header移動到了特定的sites_available配置文件中,然後運行它。 – Kip

+3

我現在花了幾個小時來使它工作,但沒有用。嘗試了各種重新安裝/排列,但我不斷收到CORS錯誤。 – deepujain

+1

@deepujain那麼可以保證它自己的SO問題,那麼一定要包括詳細的代碼示例。 –

2

首先,讓我說,看各地的網絡之後,我發現這個答案遍地開花:

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類型。

+1

它適合我,謝謝。 – user3496167

+0

設置MIME類型解決了問題。感謝@DazBaldwin。 –

0

很明顯,add_header繼承怪癖/ gotcha也適用於上游層。

我有一個腳本預授權請求意味着另一個服務,並因此返回所有其他服務的頭。

一旦我開始添加一個'Access-Control-Allow-Origin'條目以及這些中繼頭部,瀏覽器實際上會獲得條目並允許請求。

4

由於響應代碼不在允許的範圍內,所以我沒有得到響應頭的問題,除非在頭值之後指定了「always」關鍵字。

From the official docs:

添加指定的字段,只要該響應代碼等於200,201,204,206,301,302,303,304,307,或308的值可以包含一個響應報頭變量。