2013-08-26 11 views
38

Ich habe ein faszinierendes Problem, wo immer ich add_header in meinem virtuellen Host-Konfiguration auf einem Ubuntu-Server nginx mit PHP und PHP-FPM funktioniert es einfach nicht funktioniert und ich habe keine Ahnung, was ich tue falsch. Hier ist meine Config-Datei:nginx add_header funktioniert nicht

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

Ich habe versucht, das Hinzufügen der Header an den anderen Standort Abschnitte, aber das Ergebnis ist das gleiche.

Jede Hilfe wird geschätzt !!

+1

schließlich eine Frage finden, wie ich fast genau das gleiche Problem, aber keine Antwort :( –

Antwort

-2

Es stellt sich heraus, dass nginx auf die neueste Version zu aktualisieren versuchen, dies verursacht wurde. Ich hatte vorher versucht, neu zu installieren, das schien, es wieder richtig zu installieren, aber tatsächlich entfernte Ubuntu nginx nicht richtig. Also musste ich nur den Ubuntu-Server neu installieren und alles neu installieren, nur mit den Standard-Ubuntu-Repositories. Zum einen

0

Was sagt Ihr Nginx-Fehlerprotokoll?

Wissen Sie, welche add_header Zeilen die Konfiguration brechen? Wenn nicht, kommentiere sie alle aus und aktiviere sie dann 1 zu 1 und lade nginx neu, um zu sehen, welche (s) das Problem ist/sind. Ich würde zunächst den Block zu kommentieren out:

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 

Das Problem könnte sein, dass Sie Header sind Einstellung nicht durch das Kernhttpheaders Modul unterstützt. Die Installation der NginxHttpHeadersMoreModule kann hilfreich sein.

Versuchen Sie auch, die beiden add_header Linien die location ~* \... mit der folgenden int ersetzt:

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

Gibt es einen Grund, warum Sie die gzip-Konfiguration hier und nicht in Ihrem globalen nginx.conf haben?

+1

Ich glaube nicht httpheaders ist selektiv über Header fügt es. – kravietz

22

Wenn ich die oben add_header Einstellungen testen mit:

# nginx -t && service nginx reload 

ich

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 

So ist die beklagen ist reagarding diese Zeile:

add_header PS 1 

das Semikolon fehlt (;)

die Header Um zu testen, ich

# curl -I http://example.com 

Nach dem ngx_http_headers_module manual

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

Ich versuchte weiter

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

im Zusammenhang mit http, server und location, aber es nutzen möchten erschien nur im server Kontext.

62

Es gab zwei Probleme für mich.

Einer ist, dass nginx nur die letzteadd_header verarbeitet, die es einen Baum aufspürt. Wenn Sie also einen add_header im server Kontext haben, dann wird ein anderer im verschachtelten Kontext location nur die add_header Direktive innerhalb des location Kontextes verarbeiten. Nur der tiefste Kontext.

Aus dem NGINX docs auf add_header:

Es könnte mehrere add_header Richtlinien sein. Diese Direktiven werden genau dann von der vorherigen Ebene übernommen, wenn auf der aktuellen Ebene keine add_header-Direktiven definiert sind.

Zweites Problem war, dass der location/{} Block I anstelle hatte, war eigentlich nginx auf den anderen location ~* (\.php)$ Block Senden (weil es alle Anforderungen, die durch index.php repath würde, und das macht eigentlich nginx Prozess diesen php Block). Also, meine add_header Direktiven in der ersten Location Directive waren nutzlos, und es begann zu arbeiten, nachdem ich alle Anweisungen, die ich brauchte, in die PHP-Location-Direktive eingefügt hatte.

Schließlich ist hier meine Arbeitskonfiguration, um CORS im Kontext eines MVC-Frameworks namens Laravel zu ermöglichen (Sie könnten dies leicht ändern, um jedes PHP-Framework zu verwenden, das index.php als einzigen Einstiegspunkt für alle Anfragen hat).

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

Der Kern für die oben unter: https://gist.github.com/adityamenon/6753574

+2

Danke, das hat mir geholfen, mein Problem zu beheben. Ich hatte habe einen Header in nginx.conf hinzugefügt, aber es hat nicht gedauert.Nachdem ich das gelesen habe, habe ich den add_header in die spezifische sites_available Konfigurationsdatei verschoben und dann hat es geklappt. – Kip

+3

Ich habe jetzt einige 10 Stunden gebraucht um es zum Laufen zu bringen, aber nutzlos Ich habe versucht, verschiedene Neuinstallationen/Permutationen, aber ich bekomme immer wieder CORS Fehler. – deepujain

+1

@deepujain gut, dass eine SO Frage von sich selbst dann sicherstellt, um detaillierte Codebeispiele zu enthalten. –

2

, lassen Sie mich sagen, dass rund um die Bahn nach dem suchen, ich diese Antwort gefunden tauchen überall:

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

Allerdings habe ich beschlossen, diese Frage mit einer separaten Antwort zu beantworten, da ich nur geschafft um diese spezielle Lösung zu erhalten, nachdem Sie nach weiteren zehn Stunden nach einer Lösung gesucht haben.

Es scheint, dass Nginx standardmäßig keine [korrekten] Schriftart-MIME-Typen definiert. Durch this tuorial folgenden fand ich mich folgendes könnte hinzufügen:

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

Zu meiner etc/nginx/mime.types Datei. Wie erwähnt, funktionierte die obige Lösung dann. Offensichtlich zielt diese Antwort auf das Teilen von Zeichensätzen ab, aber es ist erwähnenswert, dass die MIME-Typen möglicherweise nicht in Nginx definiert sind.

+1

Es funktioniert gut für mich, danke. – user3496167

+0

Durch das Festlegen der MIME-Typen wurde das Problem behoben. Danke @DazBaldwin. –

0

Offensichtlich gilt die add_header-Vererbung quirk/gotcha auch für die Upstream-Ebene.

Ich hatte ein Skript, das Anforderungen für einen anderen Dienst vorberechtigte und deshalb alle Header vom anderen Dienst zurückgab.

Sobald ich begann, einen "Access-Control-Allow-Origin" -Eintrag zusammen mit diesen relayed Headern hinzuzufügen, würde der Browser tatsächlich den Eintrag erhalten und die Anfrage zulassen.

4

Ich hatte das Problem, den Antwortheader aufgrund des Antwortcodes nicht innerhalb des zulässigen Bereichs zu erhalten, es sei denn, Sie geben das Schlüsselwort "immer" nach dem Headerwert an.

From the official docs:

Fügt das angegebene Feld auf einen Antwort-Header vorgesehen, daß der Antwortcode ist gleich 200, 201, 204, 206, 301, 302, 303, 304, 307 oder 308. Der Wert enthalten kann, Variablen.