J'ai un problème intriguant dans lequel chaque fois que j'utilise add_header
dans la configuration de mon hôte virtuel sur un serveur Ubuntu exécutant nginx avec PHP et php-fpm, cela ne fonctionne tout simplement pas et je n'ai aucune idée de ce que je fais mal. Voici mon fichier de 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;
}
J'ai essayé d'ajouter des en-têtes aux autres sections d'emplacement, mais le résultat est identique.
Toute aide appréciée !!
Il y avait deux problèmes pour moi.
La première est que nginx ne traite que le lastadd_header
et qu’il repère un arbre. Ainsi, si vous avez un add_header
dans le contexte server
, puis un autre dans le contexte imbriqué location
, il ne traitera que la directive add_header
dans le contexte location
. Seul le contexte le plus profond.
À partir de la documentation NGINX sur add_header :
Il pourrait y avoir plusieurs directives add_header. Ces directives sont héritées du niveau précédent si et seulement si aucune directive add_header n'est définie au niveau actuel.
Le deuxième problème était que le bloc location / {}
que j'avais mis en place envoyait réellement nginx à l'autre bloc location ~* (\.php)$
(car il repèrerait toutes les demandes par le biais de index.php
, ce qui obligerait nginx à traiter ce bloc php
. Ainsi, mes directives add_header
à l'intérieur de la première directive d'emplacement étaient inutiles, et cela a commencé à fonctionner après avoir mis toutes les directives dont j'avais besoin dans la directive d'emplacement php.
Enfin, voici ma configuration de travail pour autoriser CORS dans le contexte d’un framework MVC appelé Laravel (vous pouvez le modifier facilement pour s’adapter à tout framework PHP disposant de index.php
comme point d’entrée unique pour toutes les demandes).
serveur { root /path/to/app/public; index index.php; nom_serveur test.dev; # redirection vers index.php emplacement/{ try_files $ uri $ uri//index.php?$query_string; } # transmettez les scripts PHP au serveur FastCGI à l'écoute de 127.0.0.1:9000 emplacement ~\.php $ { fastcgi_split_path_info ^ (. + \. php) (/.+) $; # NOTE: Vous devriez avoir "cgi.fix_pathinfo = 0;" dans php.ini # Avec php5-fpm: fastcgi_pass unix: /var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; # configuration cors # liste blanche des domaines autorisés, via une expression régulière # if ($ http_Origin ~ * (http: // localhost (: [0-9] +)?))) { if ($ http_Origin ~ *. *) {# ouais, pour le développement local. adaptez votre regex au besoin set $ cors "true"; } # apparemment, les trois instructions if suivantes créent un drapeau pour les "conditions composées" if ($ request_method = OPTIONS) { set $ cors "$ {cors} options"; } if ($ request_method = GET) { set $ cors "$ {cors} get"; } if ($ request_method = POST) { set $ cors "$ {cors} post"; } # traite maintenant le drapeau 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; # valeur de contrôle en amont de cache pendant 20 jours add_header 'Méthodes d'accès-contrôle-autoriser-' 'GET, POST, OPTIONS'; add_header Autorisation 'Access-Control-Allow-Headers' ', type de contenu, accepter, origine, agent utilisateur, DNT, contrôle du cache, X-Mx-ReqToken, persistance, demande X avec, si modifiée -Puisque'; add_header 'Content-Length' 0; add_header 'Content-Type' 'text/plain charset = UTF-8'; retournez 204; } } error_log /var/log/nginx/test.dev.error.log; access_log /var/log/nginx/test.dev.access.log; Buch
L'essentiel pour ce qui précède est à: https://Gist.github.com/adityamenon/6753574
Lorsque je teste les paramètres add_header
ci-dessus avec:
# nginx -t && service nginx reload
Je reçois
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
La plainte concerne donc cette ligne:
add_header PS 1
manque le point-virgule (;
)
Pour tester les en-têtes que j'aime utiliser
# curl -I http://example.com
Selon le ngx_http_headers_module manual
syntax: add_header name value;
default: —
context: http, server, location, if in location
J'ai encore essayé
add_header X-test-A 1;
add_header "X-test-B" "2";
add_header 'X-test-C' '3';
dans le contexte de http
, server
et location
, mais cela n'apparaît que dans le contexte server
.
J'avais le problème de ne pas obtenir l'en-tête de réponse car le code de réponse ne se situait pas dans la plage autorisée, sauf si vous spécifiez le mot clé "always" après la valeur de l'en-tête.
D'après les documents officiels:
Ajoute le champ spécifié à un en-tête de réponse à condition que le code de réponse soit égal à 200, 201, 204, 206, 301, 302, 303, 304, 307 ou 308. La valeur peut contenir des variables.
Tout d’abord, laissez-moi vous dire qu’après avoir regardé sur le Web, j’ai trouvé cette réponse partout:
location ~* \.(eot|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
}
Cependant, j'ai décidé de répondre à cette question par une réponse distincte, car je n'ai réussi à faire fonctionner cette solution particulière qu'après une dizaine d'heures supplémentaires à la recherche d'une solution.
Il semble que Nginx ne définisse aucun type MIME de police [correct] par défaut. En suivant ce tuorial j'ai découvert que je pouvais ajouter ce qui suit:
application/x-font-ttf ttc ttf;
application/x-font-otf otf;
application/font-woff woff;
application/font-woff2 woff2;
application/vnd.ms-fontobject eot;
À mon fichier etc/nginx/mime.types
. Comme indiqué, la solution ci-dessus a ensuite fonctionné. De toute évidence, cette réponse vise à partager les polices, mais il convient de noter que les types MIME peuvent ne pas être définis dans Nginx.
Il est évident que l'excentricité/gotcha de l'héritage add_header s'applique également à la couche en amont.
J'avais un script pré-autorisant les demandes destinées à un autre service et renvoyais donc tous les en-têtes de l'autre service.
Une fois que j'ai commencé à ajouter une entrée "Access-Control-Allow-Origin" avec ces en-têtes relayés, le navigateur obtiendrait l'entrée et autoriserait la requête.
Que dit votre journal des erreurs nginx?
Savez-vous quelles lignes add_header cassent la configuration? Sinon, commentez-les tous, puis activez-les 1 par 1, en rechargeant nginx pour voir lequel est le problème. Je commencerais par commenter le bloc:
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
Le problème peut être que vous définissez des en-têtes qui ne sont pas pris en charge par le module httpHeaders principal. L'installation de NginxHttpHeadersMoreModule peut être utile.
Essayez également de remplacer les deux lignes add_header
dans le location ~* \...
par ce qui suit:
add_header Pragma '';
add_header Cache-Control 'public, max-age=31536000'
Y a-t-il une raison pour laquelle vous avez la configuration gzip ici et pas dans votre nginx.conf global?