Question Comment faire en sorte que Nginx redirige toutes les demandes de fichiers qui n'existent pas vers un seul fichier php?


J'ai la configuration nginx vhost suivante:

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

    try_files $uri /index.php;

    location ~ \.php$ {
            if (!-f $request_filename) {
                    return 404;
            }

            fastcgi_pass localhost:9000;
            fastcgi_param SCRIPT_FILENAME /path/to/site/dir/webroot$fastcgi_script_name;
            include /path/to/nginx/conf/fastcgi_params;
    }
}

Je veux rediriger toutes les demandes qui ne correspondent pas aux fichiers existants vers index.php. Cela fonctionne très bien pour la plupart des URI en ce moment, par exemple:

example.com/asd
example.com/asd/123/1.txt

Ni de asd ou asd/123/1.txt existent pour qu'ils soient redirigés vers index.php et cela fonctionne très bien. Cependant, si je mets dans l'URL example.com/asd.php, il essaie de chercher asd.php et quand il ne peut pas le trouver, il retourne 404 au lieu d'envoyer la demande à index.php.

Y a-t-il un moyen d'obtenir asd.php être aussi envoyé à index.php si asd.php n'existe pas?


6
2018-01-05 14:33


origine


Vous pouvez simplement réécrire ^ /index.php; au lieu de retour 404; - Martin Fjordvald
Voir mon commentaire sous la réponse de Tyoyengel - J'ai besoin d'un moyen de dire au fichier index.php à utiliser error/404 comme le chemin - Richard


Réponses:


Si vous prenez en compte vos commentaires supplémentaires, cela semble être le moyen le plus optimal, bien que ce ne soit pas une jolie configuration.

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        try_files $uri @missing;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /path/to/nginx/conf/fastcgi_params;
    }

    location @missing {
        rewrite ^ /error/404 break;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        include /path/to/nginx/conf/fastcgi_params;
    }
}

10
2018-01-05 17:59



il est censé y avoir un point-virgule à la fin de cette ligne try_files - jab11
@ jab11 Oui! Ajouté que maintenant. - Martin Fjordvald


Wow, je pense que tout ce que vous voulez remplacer ce code est:

error_page 404 /index.php

... Si je lis ce que vous voulez correctement.


3
2018-01-05 15:08



Cela fonctionne bien, et j'ai donc error_page 404 /error/404/ qui redirige ensuite vers index.php, mais ensuite dans le php request_uri (ce que j'utilise pour obtenir le chemin demandé), il a asd.php (en supposant que c’est ce qui a été tapé et a abouti au 404) et que je n’ai aucun moyen d’obtenir la error/404chemin pour ensuite agir dans le php. Est-il possible de passer ce chemin vers php? C'EST À DIRE. Je veux toujours un index.php avant unique pour gérer les erreurs aussi. Comment puis-je dire au fichier index.php qu'il s'agit d'une erreur à gérer? - Richard


Ce que vous essayez de faire est identique à la page d'erreur personnalisée. Vous pouvez utiliser la propriété error_page de nginx pour y parvenir. Suivez le lien pour plus d'informations

http://wiki.nginx.org/HttpCoreModule#error_page


2
2018-01-05 15:08





Je pense que le problème est que vous utilisez "try_files" avec une déclaration "if" à votre emplacement. Dans la documentation, try_files est supposé remplacer les vérifications d’existence de style if et mod_rewrite. Depuis le wiki nginx, la page "try_files" ( http://wiki.nginx.org/HttpCoreModule#try_files ):

"try_files est fondamentalement un remplacement du contrôle d'existence typique des fichiers / répertoires de style mod_rewrite. Il est censé être plus efficace que d'utiliser if - voir IfIsEvil"

Vérifiez la page wiki "si" ( http://wiki.nginx.org/NginxHttpRewriteModule#if ):

"note: Avant d’utiliser if, veuillez consulter la page if est evil et envisagez plutôt d’utiliser try_files."

Donc, essayez de supprimer cela si cocher et rester juste avec les "try_files". Cela devrait vérifier l'existence de toute page (y compris asd.php ou quoi que ce soit d'autre dans end .php) et revenir à index.php si elle ne la trouve pas.


1
2018-01-05 15:19



La déclaration if vise à prévenir une éventuelle faille de sécurité décrite ici: blog.martinfjordvald.com/2010/07/nginx-primer (lié de wiki.nginx.org/Configuration). C'est une exception à la règle de ne pas utiliser d'instructions if dans les blocs de localisation. - Richard


Cela a fonctionné avec moi!

    location /anyfolder {
        error_page 404 /yourhandler.php?fnf=$uri;
    } 

0
2017-07-27 04:06





Richard, selon le guide des pièges, recommande de définir «cgi.fix_pathinfo = 0 ″ dans php.ini lorsqu’il résout un potentiel vulnérabilité entre nginx et php.


0
2018-01-09 17:47





Je veux rediriger tous les fichiers php manquants vers des fichiers internes personnalisés /error404 page d'erreur. Je vais poster ma solution trouvée lors de la permutation.

error_page 404 /error404;

ne m'a pas aidé. Les combinaisons de location, @missing, rewrite et break. Mais

location ~ \.php$ {
    # this is it! $fastcgi_script_name points to my url
    try_files $fastcgi_script_name = /error404; 
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
    ...
    etc.

0
2018-02-02 14:00