如何在 nginx 上从/file.php 重定向到/file? [英] How redirect from /file.php to /file on nginx?
问题描述
我目前正在使用此配置从我的 nginx 服务器上的 url 中隐藏 .php 扩展名:
I'm currently hiding the .php extension from the urls on my nginx server with this configuration:
location / {
try_files $uri $uri/ @extensionless-php;
index index.html index.htm index.php;
}
location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location @extensionless-php {
rewrite ^(.*)$ $1.php last;
}
这工作得很好,但是如何让 nginx 不允许添加 .php 扩展名?.在我的示例中,如果您手动删除 .php,它会起作用,但如果您添加它,它会在 url 中保持永久状态.
This is working perfectly, but how can I make nginx not allow adding the .php extension?. In my example if you manually delete the .php it works but if you add it it remains permanent in the url.
推荐答案
要使用 HTTP 301 代码永久重定向这些请求,请尝试
To redirect those requests permanently with HTTP 301 code try
rewrite ^(.*)\.php$ $1 permanent;
将此指令放在您的 location
块之前.
Put this directive before your location
blocks.
更新
在回答这个问题后,OP 提出了另一个问题(现在被删除了)——如果你有以下 webroot 结构怎么办:
After this being answered, OP asked another question (now being deleted) - what if you have the following webroot structure:
webroot
|
+-- index.php (PHP file)
|
+-- somename.php (PHP file)
|
+-- somename (folder)
| |
| +-- index.php (PHP file)
|
+-- someothername (folder)
|
+-- index.php (PHP file)
以前的解决方案无法提供 somename.php
文件,因为对 http://example.com/somename
的请求将被 try_files 重定向
指令到 http://example.com/somename/
,接下来将与 somename/index.php
文件一起提供.
Previous solution makes it impossible to serve somename.php
file, because the request to http://example.com/somename
would be redirected by try_files
directive to http://example.com/somename/
and in next turn would be served with somename/index.php
file.
这可以解决,但您必须停止使用 index
和 try_files
指令并使用您自己的请求处理逻辑模拟它们的行为.这就是我最终的结果:
This can be solved, but you'll have to stop using index
and try_files
directives and emulate their behavior with your own request processing logic. This is what I've ended up with:
map $original_uri $maybe_slash {
~/$ '';
default '/';
}
server {
...
if ($original_uri = '') {
set $original_uri $uri;
}
# redirect requests of '/somepath/somefile.php' to '/somepath/somefile'
rewrite ^(.*)\.php$ $1 pemanent;
location / {
# this emulates 'try_files $uri $uri/ ...' directive behavior and redirects '/some/path'
# to '/some/path/' if 'some/path.php' file does not exists, but 'some/path' folder exists
# and there are 'some/path/index.html' file in that folder
set $check_redirect $rewrited$maybe_slash;
if ( $check_redirect = '1/' ) {
return 301 $original_uri/$is_args$args;
}
if ( -f $document_root$uri.php ) { rewrite ^ $uri.php last; }
# this emulates 'index index.php index.html' directive behavior
if ( -f $document_root$uri${maybe_slash}index.php ) {
set $rewrited 1;
rewrite ^ $uri${maybe_slash}index.php last;
}
if ( -f $document_root$uri${maybe_slash}index.html ) {
set $rewrited 1;
rewrite ^ $uri${maybe_slash}index.html last;
}
# if a request for an absent resource should be served with some backend
# controller, it is ok to use some 'try_files' directive here like
# try_files $uri /index.php?path=$original_uri;
}
location ~ \.php$ {
# this emulates 'try_files $uri $uri/ ...' directive behavior and redirects '/some/path'
# to '/some/path/' if 'some/path.php' file does not exists, but 'some/path' folder exists
# and there are 'some/path/index.php' file in that folder
set $check_redirect $rewrited$maybe_slash;
if ( $check_redirect = '1/' ) {
return 301 $original_uri/$is_args$args;
}
# no 'try_files $uri =404' or 'include snippets/fastcgi-php.conf' here, this location
# can be reached only if requested PHP file is really exists in webroot folder
include fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root$uri;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
有了上面给出的这个配置和 webroot 结构
With this configuration and webroot structure given above
- 对
http://example.com/
的请求将通过webroot/index.php
文件提供; - 对
http://example.com/somename
的请求将通过webroot/somename.php
文件提供; - 对
http://example.com/somename.php
的请求将被重定向到http://example.com/somename
并与webroot 一起提供/somename.php
文件; - 对
http://example.com/somename/
的请求将与webroot/somename/index.php
文件一起提供; - 对
http://example.com/someothername
的请求将被重定向到http://example.com/someothername/
(因为没有webroot/someothername.php
文件存在)并与webroot/someothername/index.php
文件一起提供.
- request to
http://example.com/
would be served withwebroot/index.php
file; - request to
http://example.com/somename
would be served withwebroot/somename.php
file; - request to
http://example.com/somename.php
would be redirected tohttp://example.com/somename
and served withwebroot/somename.php
file; - request to
http://example.com/somename/
would be served withwebroot/somename/index.php
file; - request to
http://example.com/someothername
would be redirected tohttp://example.com/someothername/
(since nowebroot/someothername.php
file exists) and served withwebroot/someothername/index.php
file.
关于自定义 HTTP 错误页面的重要说明
如果您有一些自定义错误页面,例如 webroot/error/404.php
用于 HTTP 404 错误,而不是像通常那样定义它
If you have some custom error page, for example webroot/error/404.php
for HTTP 404 error, instead of usual way to define it like
error_page 404 /error/404.php;
您需要跳过该文件的 .php
扩展名:
you'd need to skip .php
extension of that file:
error_page 404 /error/404;
这篇关于如何在 nginx 上从/file.php 重定向到/file?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!