
Ich habe ein NGINX mit einer PHP-FPM-Instanz dahinter. OPTIONS
Anfragen für Pfade, für die eine Datei im Dateisystem vorhanden ist, sollten von NGINX bearbeitet werden. Für diese Anfragen sollte NGINX Access-Control-*
CORS-Header zurückgeben. OPTIONS
Anfragen, für die keine Datei vorhanden ist, sollten an PHP-FPM übergeben werden.
Die Logik sollte ungefähr so aussehen:
location / {
# In this case: Check if file exists
# - yes: return CORS headers
# - no: pass request to PHP-FPM
if ($request_method = 'OPTIONS') {
# This causes an error
try_files @cors;
}
# Normal request handling for all non-OPTIONS requests:
# Try to serve file directly, fallback to index.php if file does not exist
try_files $uri /index.php$is_args$args;
}
location @cors {
if (-f $request_filename) {
more_set_headers "Access-Control-Allow-Credentials: true";
more_set_headers "Access-Control-Allow-Origin: example.com";
more_set_headers 'Access-Control-Allow-Methods: POST, GET, DELETE, PUT, OPTIONS';
more_set_headers 'Access-Control-Allow-Headers: content-type,ngsw-bypass';
more_set_headers 'Access-Control-Max-Age: 3600';
more_set_headers 'Content-Type: text/plain; charset=UTF-8';
more_set_headers 'Content-Length: 0';
return 204;
}
try_files /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass localhost:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME /var/www/public/index.php;
fastcgi_param DOCUMENT_ROOT /var/www/public;
fastcgi_param HTTPS $fastcgi_param_https;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/index.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
Das funktioniert allerdings nicht. Since try_files
ist innerhalb einer if
Anweisung nicht zulässig ([emerg] 1#1: Die Direktive „try_files“ ist hier nicht zulässig).
Antwort1
Mit der Direktive können Sie error_page
die OPTIONS-Anfragen für Pfade verarbeiten, für die eine Datei im Dateisystem vorhanden ist.
location / {
# Try to serve file directly, fallback to index.php if file does not exist
try_files $uri /index.php$is_args$args;
# Handle OPTIONS requests for paths for which a file exists in the file system
if ($request_method = 'OPTIONS') {
if (-f $request_filename) {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
}
}
# Pass all other requests to PHP-FPM
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Die try_files
Direktive wird verwendet, um Dateien direkt bereitzustellen, mit Fallback, index.php
falls die Datei nicht existiert. Der if
Block prüft, ob die Anforderungsmethode OPTIONS ist und ob im angeforderten Pfad eine Datei vorhanden ist. Wenn beide Bedingungen erfüllt sind, fügt NGINX der Antwort die erforderlichen CORS-Header hinzu und gibt den Statuscode 204 „Kein Inhalt“ zurück.