nginx - 在 NGINX 位置块中使用 try_files 并重写,带有默认的前端控制器文件
问题描述
我正在从旧框架迁移到 php 中的新框架。旧框架对每个 URL 都有一个登录页面,例如:
test.com/page1
将被路由到public_directory/page1.php
test.com/another_page
将被路由到public_directory/another_page.php
等等
以下块用于这些请求:
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php;
}
location @php {
rewrite ^(/[^/]+)$ $1.php last;
rewrite ^(/[^/]+)/(.*)$ $1.php?q=$2 last;
}
新框架使用前端控制器,每个请求都需要定向到public_directory/front_controller.php
. 当我们迁移时,我们正在删除旧的登录文件,这是我们可以识别哪些页面使用新框架的方式。
我认为会起作用的是,在@php
块之后,将默认参数添加到front_controller.php
:
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php /front_controller.php?$arg;
}
location @php {
rewrite ^(/[^/]+)$ $1.php last;
rewrite ^(/[^/]+)/(.*)$ $1.php?q=$2 last;
}
如果@php 重写块不匹配文件,那么它应该默认为/front_controller.php?arg
; 但是,我发现现在@php 被忽略,nginx
而是直接转到front_controller.php。我哪里错了,为什么@php重写现在被忽略了?
解决方案
该try_files
指令需要一个文件列表,后跟 URI / 命名位置 / HTTP 错误代码,如果列表中的文件都不存在,则将使用该列表。假设您的站点根目录是/home/user/www
并且您的请求是http://example.com/some/path
此配置,请检查以下文件/目录是否存在:
/home/user/www/some/path
文件,如果找到该文件,它的内容将在响应正文中返回。/home/user/www/some/path/
目录,如果该目录存在,将检查该index
指令定义的所有可能的索引文件,将使用第一个找到的文件。如果在此目录中没有找到索引文件,则 nginx 如果有则返回目录内容,autoindex on;
否则返回 HTTP 403 Forbidden。/home/user/www@php
文件。显然,找不到该文件。
如果这些检查都没有成功,nginx 将遵循定义为最后一个参数的 URI(或命名位置)(/front_controller.php?$arg
在这种情况下)。
你可以做的是尝试类似的东西
location ~ ^(/[^/]+)$ {
try_files $1.php /front_controller.php?$arg;
}
location ~ ^(?<script>/[^/]+)/(?<param>.*)$ {
rewrite ^ $script?q=$param last;
}
但是我不明白$arg
变量应该来自哪里。也许你的意思是$is_args$args
?
更新
我错了,您可以使用指令检查 php 脚本是否存在try_files
,但该脚本不会传递到您的 php 处理程序位置块。你的任务引起了我的兴趣,最后我得到了一些工作:
# backup original args
set $original_args $args;
if ($uri ~ "^(/[^/]+)(?:/(.*))?$") {
set $script $1.php;
set $param $2;
}
if ($param) {
set $args "q=$param";
}
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php;
}
location @php {
if ( !-f $document_root$script ) {
# old landing php file is absent, restore original args and rewrite URI to /front_controller.php
set $args $original_args;
set $script /front_controller.php;
}
rewrite ^ $script last;
}
推荐阅读
- javascript - 自动字符串内存优化
- python - 如何使用 BeautifulSoup 从“a”元素中提取文本?
- flutter - 在真实设备上向服务器发出任何 Http 请求时颤动在日志中报告错误的端口号
- javascript - 通过具有特殊字符的括号表示法向 JS 对象添加字段
- arrays - 我在 python 中的 for 循环和输入遇到问题
- html - 按下 Edge 上的提交按钮时,表格标题的 CSS 有时会消失
- regex - 使用 google sheet 或 excel 公式从字符串中删除除数字和字母之外的所有内容
- typescript - Ant design Table dataIndex不适用于搜索选项时
- javascript - 触发一次后事件不会重新触发?
- flutter - NeverScrollableScrollPhysics() 无法正常工作,需要有关选项卡填充/边距的建议