【问题标题】:How to replace characters in an nginx variable string?如何替换 nginx 变量字符串中的字符?
【发布时间】:2018-09-17 07:02:17
【问题描述】:

有没有办法可以用空格(或+)替换以$request_uri 返回的非字母数字字符?

我想要做的是将我的一个站点中的所有 404 重定向到它的搜索引擎,其中查询是请求的 uri。所以,我的 nginx.conf 中有一个块,其中包含:

error_page 404 = @notfound;
location @notfound {
    return 301 $scheme://$host/?s=$request_uri;
}

虽然这确实有效,但它返回的 url 是实际的 uri 完整的 -_/ 字符导致搜索始终返回 0 个结果

例如...给出这个网址:https://example.com/my-articles,重定向结束为:https://example.com/?s=/my-articles

我想要(最终)这样结束:https://example.com/?s=my+articles(不过,开头的 + 也可以正常工作...https://example.com/?s=+my+articles

我需要在没有 LUA 或 Perl 模块的情况下执行此操作。那么,我该如何实现呢?

【问题讨论】:

  • 你能提供一些其他的样本(网址)
  • 边走边编……问题已经够详细了

标签: regex string nginx replace


【解决方案1】:

你可能需要根据你希望替换的目录结构向下调整它,但这是基本概念。

最初捕获 404 的命名位置:

location @notfound {
  rewrite (.*) /search$1 last;
}

命名位置有点限制,所以所有这一切都是在返回 404 的 URI 的开头添加/search/last 标志告诉 Nginx 跳出当前位置并选择要处理的最佳位置基于重写的 URI 的请求,所以我们需要一个块来捕获它:

location ^~ /search/ {
  internal;
  rewrite ^/search/(.*)([^a-z0-9\+])(.*)$ /search/$1+$3 last;
  rewrite ^/search/(.*)$ /?s=$1 permanent;
}

internal 指令使该位置只能由 Nginx 进程本身访问,任何客户端对该块的请求都将返回 404。

第一次重写会将最后一个非文本、数字或+ 字符更改为+,然后要求 Nginx 重新评估重写的 URI。

位置块是使用^~ 修饰符定义的,这意味着匹配此位置的请求将不会针对任何正则表达式定义的位置块进行评估,因此该块应继续捕获重写的请求。

一旦所有非单词字符都消失了,第一次重写将不再匹配,因此请求将被传递到下一次重写,这会从 URI 前面删除 /search 并添加查询字符串。

我的日志如下所示:

>> curl -L -v http://127.0.0.1/users-forum-name.1
<<  "GET /?s=users+forum+name+1 HTTP/1.1"

>> curl -L -v http://127.0.0.1/users-forum-name/long-story/some_underscore
<< "GET /?s=users+forum+name+long+story+some+underscore"

你明白了..

【讨论】:

  • 嗯...由于某种原因,这对我不起作用。你可以测试:https://gyo.im/this-is-a-dummy?_=12
  • hmm....所以,我必须添加fastcgi_intercept_errors,以便开始处理404,但是,它为我提供了https://gyo.im/?s=index+php&amp;q=/this-is-a-dummy&amp;_=12
  • 您的初始请求有一个查询字符串,因此您需要摆脱它。添加? 或使用set $args ''; index.php 从某处出现,所以猜你在indextry_files 指令中指定了它?
  • 目前我已经实现了混合重定向。使用我发布的 nginx 配置,但重定向到清理输入的 php 文件,进行字符串替换,然后重定向
【解决方案2】:

您可以使用 lua 模块,使用 lua 字符串函数将此变量转换为您需要的变量。我正在使用 OpenResty,它基本上是启用了 lua 的 nginx。但是 nginx lua 模块会很好。这是允许您在 nginx 配置中使用 lua 的指令。它可以使用content_by_lua_block / access_by_lua_block 在内部位置,也可以使用content_by_lua_file / access_by_lua_file 在单独的文件中。这是有关此 https://github.com/openresty/lua-nginx-module#content_by_lua 的文档。 这是我的应用程序中的一个示例。

location ~/.*\.jpg$ {

  set $test '';
  access_by_lua_block {

    ngx.var.test = string.sub(ngx.var.uri, 2)

  }
  root /var/www/luaProject/img/;
  try_files    $uri /index.html;


  }

【讨论】:

  • I will need to do this without LUA or Perl modules. So, how can I accomplish this?
  • 如果没有 LUA,我会尝试像其他 anwsers 显示的那样进行重写。为什么不直接使用模块?
【解决方案3】:
  1. 自动发出从404 Not Found 页面到其他地方的重定向通常是一个坏主意——用户可能只是在 URL 中输入了错误的单个字符(例如,在手机上从传单中复制 URL 时)并且有一个“胖手指”),一旦他们看到 404 和地址栏中明显的拼写错误,这将很容易纠正,但如果您的搜索引擎无法提供,则可能需要从头开始。

  2. 如果您仍然想这样做,在搜索引擎本身内执行它可能会更有效 - 毕竟,如果您的搜索引擎无法通过 URL 搜索和更正拼写错误,那么它听起来好像不是一个非常有用的搜索引擎,是吗?

  3. 如果您仍然想在搜索引擎前单独在 nginx 中执行此操作,那么您可以使用 http://nginx.org/r/rewrite 指令本质上让您实现任何类型的 DFA(确定性有限自动机)这一事实,但是,取决于需要的替换次数,可能会导致循环过多和规则集有些不灵活。

    查看以下有关在 URL 中将给定字符递归替换为其他字符的资源:

【讨论】:

  • 对不起伙计,根据问题,#1 没用。我不需要意见......我问了一个问题来寻找答案......如果我想要意见,我会点击Facebook。 #2 这是一个 wordpress 网站。 #3,我会看看那些...正如我在另一条评论中所说,我现在有一个解决方法
猜你喜欢
  • 1970-01-01
  • 2020-07-09
  • 2020-03-30
  • 2013-02-16
  • 1970-01-01
  • 2021-10-27
  • 2020-02-04
  • 1970-01-01
相关资源
最近更新 更多