2013-08-26 22 views
38

Ho un problema intrigante in cui ogni volta che uso add_header nella configurazione del mio host virtuale su un server ubuntu su cui gira nginx con PHP e php-fpm semplicemente non funziona e non ho idea di cosa sto facendo sbagliato. Ecco il mio file di configurazione:nginx add_header non funziona

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

Ho provato ad aggiungere le intestazioni alle altre sezioni posizione, ma il risultato è lo stesso.

Qualsiasi aiuto apprezzato !!

+1

Infine trovare una domanda che ha quasi esattamente lo stesso problema come me, ma nessuna risposta :( –

risposta

-2

Si scopre che il tentativo di aggiornare nginx alla versione più recente stava causando questo. Avevo provato in precedenza a reinstallare che sembrava reinstallarlo correttamente, ma in realtà Ubuntu non stava rimuovendo nginx correttamente. Quindi tutto ciò che dovevo fare è reinstallare il server Ubuntu e installare tutto di nuovo usando solo i repository ubuntu standard.

0

Che cosa dice il log degli errori di nginx?

Sapete quali linee add_header stanno interrompendo la configurazione? Altrimenti, commentali tutti e poi abilitali 1 per 1, ricaricando nginx per vedere quale/i è/sono il problema. Vorrei cominciare commentando il blocco:

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 

Il problema potrebbe essere che si sta impostando le intestazioni non supportate dal modulo httpHeaders core. L'installazione di NginxHttpHeadersMoreModule potrebbe essere utile.

Inoltre, provare a sostituire le due linee add_header int la location ~* \... con il seguente:

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

C'è una ragione si ha la configurazione di gzip qui e non nel tuo nginx.conf globale?

+1

Non credo httpHeaders è selettiva sulle intestazioni, aggiunge. – kravietz

22

Quando ho testare le suddette add_header impostazioni con:

# nginx -t && service nginx reload 

ottengo

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 

Così il lamentano è torna in linea:

add_header PS 1 

manca il punto e virgola (;)

Per testare le intestazioni mi piace usare

# curl -I http://example.com 

Secondo il ngx_http_headers_module manual

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

ho cercato ulteriori

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

nel contesto http, server e location, ma visualizzato solo nel contesto server.

62

C'erano due problemi per me.

Uno è che nginx elabora solo lo ultimoadd_header che si abbassa su un albero. Pertanto, se si dispone di un add_header nel contesto server, quindi di un altro nel contesto nidificato location, elaborerà solo la direttiva add_header all'interno del contesto location. Solo il contesto più profondo.

Dalla documentazione nginx su add_header:

Ci possono essere varie direttive add_header. Queste direttive sono ereditate dal livello precedente se e solo se non ci sono direttive add_header definite al livello corrente.

secondo problema era che il blocco location/{} che avevo in luogo era in realtà l'invio di nginx all'altro location ~* (\.php)$ blocco (perché sarebbe repath tutte le richieste attraverso index.php, e che in realtà rende processo nginx questo php blocco). Quindi, le mie direttive add_header all'interno della prima direttiva di posizione erano inutili, e ha iniziato a funzionare dopo aver inserito tutte le direttive di cui avevo bisogno all'interno della direttiva di localizzazione php.

Infine, ecco la mia configurazione di lavoro per consentire CORS nel contesto di un framework MVC chiamato Laravel (è possibile modificarlo facilmente per adattarsi a qualsiasi framework PHP che ha index.php come un unico punto di ingresso per tutte le richieste).

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

Il nocciolo per quanto sopra è a: https://gist.github.com/adityamenon/6753574

+2

Grazie, questo mi ha aiutato a risolvere il mio problema. Ho avuto ha aggiunto un'intestazione in nginx.conf, ma non è stata presa. Dopo aver letto questo, ho spostato l'add_header nel file di configurazione sites_available specifico e poi ha funzionato. – Kip

+3

Ora ho impiegato poche decine di ore per farlo funzionare ma non serve Ho provato varie reinstallazioni/permutazioni, ma continuo a ricevere errori CORS. – deepujain

+1

@deepujain bene che garantisce una domanda SO propria quindi, assicurarsi di includere esempi di codice dettagliati. –

2

In primo luogo, vorrei dire che dopo aver guardato giro per il web, ho trovato questa risposta spuntando ovunque:

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

Tuttavia, ho deciso di rispondere a questa domanda con una risposta separata come ho solo riuscito per far funzionare questa particolare soluzione dopo aver impiegato circa altre dieci ore alla ricerca di una soluzione.

Sembra che Nginx non definisca alcun tipo di carattere MIME [corretto] per impostazione predefinita. Seguendo this tuorial ho trovato che potrei aggiungere il seguente:

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

Per il mio file etc/nginx/mime.types. Come detto, la soluzione di cui sopra ha funzionato. Ovviamente, questa risposta è mirata alla condivisione dei caratteri, ma vale la pena notare che i tipi MIME potrebbero non essere definiti in Nginx.

+1

Funziona bene per me, grazie. – user3496167

+0

L'impostazione dei tipi MIME ha risolto il problema. Grazie a @DazBaldwin. –

0

Evidentemente anche l'ereditarietà di add_header quirk/gotcha si applica al livello upstream.

Avevo uno script che pre-autorizzava le richieste relative a un altro servizio e pertanto restituiva tutte le intestazioni dall'altro servizio.

Una volta che ho aggiunto una voce "Access-Control-Allow-Origin" insieme a queste intestazioni inoltrate, il browser otterrebbe effettivamente la voce e consentirà la richiesta.

4

Avevo il problema di non ottenere l'intestazione della risposta a causa del codice di risposta non compreso nell'intervallo consentito, a meno che non si specifica la parola chiave "always" dopo il valore dell'intestazione.

From the official docs:

aggiunge il campo specificato in un'intestazione di risposta condizione che il codice di risposta uguale a 200, 201, 204, 206, 301, 302, 303, 304, 307 o 308. Il valore può contenere variabili.

Problemi correlati