【问题标题】:Nginx rewrite rule (with try_files?) filename.php?text=$args (to) foldername/?text=$argsNginx 重写规则(使用 try_files?) filename.php?text=$args (to) foldername/?text=$args
【发布时间】:2017-08-28 11:30:05
【问题描述】:

当我使用此请求发送参数 example.com/index.php?text=s1&sort=s2 时,如何在 nginx 中重写规则,但我希望 nginx 将其处理为example.com/process/?text=s1&sort=s2 ?

“s1”和“s2”是您在搜索表单中输入的内容。

我已经试过了:

rewrite ^/index.php?text=(.*)$ /process/?text=$1 last;

还有这个:

location ~* /index.php?text=(.*)$ {
try_files $uri /search/?text=$1;
#try_files $uri /search/?text=$is_args$args;
}

还有这个..

location =index.php?text=$1&sort=$2 {
rewrite index.php?text=$1&sort=$2 /process/text=$1&sort=$2;
}

但不知何故,它不起作用。

这是我配置的主要部分:

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

location ~* \.php$ {
include /etc/nginx/php_params;
include /etc/nginx/fastcgi_params;
}

我很困惑..:/

【问题讨论】:

  • 请不要在这里使用.htaccess标签——它不适用于nginx。我已经删除了标签。
  • /index.php 是否用于其他用途?或者我可以重写任何以/index.php开头的URI吗?
  • 是的,它已经用于缩短其他 url 路径。例如,我可以使用“site.com/register”来这里 -> site.com/index,php/?register 或 site.com/login -> site.com/index.php?/login。实际上,它适用于 Codeigniter 框架。
  • 抱歉,我在原始请求中拼错了一个单词。不是 example.com/index.php?q=s1&sort=s2 ,而是 example.com/index.php?text=s1&sort=s2 - 现在已修复。检查你的答案..

标签: nginx url-rewriting


【解决方案1】:

? 之后的任何内容都是查询字符串的一部分,并且可以使用以 arg_ 前缀开头的变量名来访问各个值。

可以使用以下方式定义所有/index.php 的简单重写:

location = /index.php {
    rewrite ^ /process/?text=$arg_q&sort=$arg_sort? last;
}

最后的? 防止rewrite 将旧查询字符串附加到新URI 的末尾。

如果您希望仅找出那些包含 $arg_q 参数的 URI,则需要在 PHP 位置块内使用 evil if。像这样:

location ~* \.php$ {    
    if ($arg_q) {
        rewrite ^/index.php$ /process/?text=$arg_q&sort=$arg_sort? last;
    }
    ...
}

编辑:

1) 在您的情况下,URI 主要由/index.php 处理,但$request_uri 的值(请求的原始值)用于在/index.php 内路由它。如果不执行外部重定向,$request_uri 的值很难修改。

2) 当/index.php 显示为原始请求时,您希望将其路由到/search/$request_uri 的当前值以 /index.php 开头,这是无用的。

解决方案是识别$request_uri 的无用值并执行外部重定向以修改$request_uri 的值。像这样的:

if ($request_uri ~ ^/index.php) {
    return 302 /search/?$args;
}
location / {
    try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.php$ {
    ...
}

如果查询字符串相同,只需使用$args(或$query_string)追加即可。否则,就像我原来的答案一样,将其分解为单独的论点。

【讨论】:

  • 我在 PHP 位置块中使用了您的答案中的示例: if ($arg_text) { rewrite ^/index.php$ /search/?text=$arg_text&sort=$arg_sort?最后的;但不幸的是出现错误(500):[error] 6163#0: *1 rewrite or internal redirect cycle while processing "/search/", client: xxx.xxx.xx.xxx, server: _, request: " GET /index.php?text=test&sort=test2 HTTP/1.1"
  • 我理解这个问题。这取决于您在 php_params 文件中的内容,但最初,您可以尝试将 last 更改为 (1) redirect 或 (2) break
  • 感谢您的帮助。我在浏览器中还有两个错误:重定向(..以永远不会完成的方式重定向此地址的请求..)和中断(未指定输入文件。)。也许值得尝试这样的事情: if ($args ~ text){ return 419} 并使用 arg_text 阻止处理请求,例如 error_page 419 = @arg_text; location @arg_text { ... php-fpm params here to rewrite url path..} 我相信应该可以,但不知道如何实现..
  • 问题看起来很简单 - 如果有“text”参数,只需将“/index.php/”替换为“/process/” - 但仍然无法弄清楚:) 虽然,它使用它很容易: if ($args ~ text) { rewrite /index.php/ /process/; } :D
  • @Oria 根据我运行的一些测试,我在原始答案中附加了一些细节。
【解决方案2】:

不想编辑已接受的答案 - 我想提供一个我测试过的替代解决方案:

root ...;

location / {
    try_files $uri $uri/ @index;
}

location @index {
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    fastcgi_param REQUEST_URI $uri;
    fastcgi_pass php5-fpm-sock;
}

location ~* \.php$ {
    if ($arg_text) {
        rewrite ^/index.php$ /search/ last;
    }

    try_files $uri =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass php5-fpm-sock;
}

此版本通过在命名位置中使用$uri 来避免不可变的$request_uri。通过使用index.php 的命名位置,也可以避免早期的重定向循环。

【讨论】:

  • 感谢您的另一个回答!写的很好,但是没用。正如我之前所说,我还有其他 args (index.php/?$args),如果设置如下,它们就可以工作: location / { try_files $uri $uri/ /index.php?$query_string;使用这个新配置,他们和 /search/ 与 args 都不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2014-07-01
  • 2021-01-11
  • 2017-09-19
  • 2010-11-20
相关资源
最近更新 更多