framework
framework copied to clipboard
nginx的伪静态规则应该调整为!-f,否则在某些场景下会出错。
官网文档的写法如下: 后面称为:A用法。
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}
实际上使用!-f会更好一些:
后面成为B用法。
location / {
if (!-f $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}
!-e判断的是目录或文件是否不存在,不存在时则重写。 !-f判断的是文件是否不存在,不存在时则重写。
以上虽然差别很小,但是实际上却有很大的不同。
当使用A用法时,只有get、head、post方法会进入转发,而其他的方法比如put、patch不会进行重写,这跟定义路由没有任何关系,因为这个链接根本就没有进入重写。没有执行index.php。而且会返回405错误。
此时如果我们想定义一个路由去处理这类的请求,根本不可能,因为nginx没有重写到php上。更重要的是会返回405错误。
Route::rule('/', function (Request $request) {
Log::debug('进入路由');
$method = $request->method();
Log::debug($method);
。。。。
});
然而一个极其简单的解决方案是,把A用法换成B用法。
换成B方法,就都可以将请求重写到php中。这时定义的路由文件就可以全部匹配到相应的请求。
http还有其他一些扩展请求,比如webdav的PROPFIND,MKCOL等,使用B方法也都会正常表现,此时如果是用A方法,则会返回405错误。
注意,只是请求跟目录时会发生以上情况:
https://servername/
只要带有path就不会:
https://servername/aaa
这就更需要换成B方法,因为同样的请求method,带了path,就能正常重写且不报错,不带path,就会报错,表现严重不一致。
比如使用A方法时,option请求根目录会返回405错误,但option请求带有path的路径(servername/aaa),就是正常的204 。 使用PUT请求也是如此。 但是调整为B方法,则是否带有path,都会表现一致。