【问题标题】:Nginx location match regex for special characters and encoded url charactersNginx 位置匹配正则表达式的特殊字符和编码的 url 字符
【发布时间】:2019-01-15 17:56:40
【问题描述】:

我今天尝试了很多事情,但我没有获胜。我的站点中有一个文件是偶然创建的,其中包含一个特殊字符。因此,Googlebot 已停止抓取 3 周,并且网站管理员工具/搜索控制台不断通知我并希望重新测试该网址。

我想要实现的只是配置 Nginx 以匹配以下请求并将它们重定向到正确的位置,但正则表达式让我难倒这个。

未编码的 URL 字符串为:

/historical-rainfall-trends-south-africa-1921–2015.pdf

编码后的 URL 字符串为:

/historical-rainfall-trends-south-africa-1921%C3%A2%E2%82%AC%E2%80%9C2015.pdf

如何获得这些位置匹配?

更新:

仍然失去理智,我尝试过的任何方法都不起作用。 我在这里得到了这个正则表达式的匹配 - https://regex101.com/r/3Lk2zr/3

然后使用这个

location ~ /.*[^\x00-\x7F]+.* { return 444; }

仍然给我一个 404 而不是 444

同样,我得到了一个匹配 - https://regex101.com/r/80KWJ8/1 但后来

location ~ /.*([^?]*)\%(.*)$ { return 444; }

给出 404 而不是 444 ??????

也试过了,但还是不行。来源:https://serverfault.com/questions/656096/rewriting-ascii-percent-encoded-locations-to-their-utf-8-encoded-equivalent

location ~* (*UTF8).*([^?]*)\%(.*)$ { return 444; }

location ~* (*UTF8).*[^\x00-\x7F]+.* { return 444; }

临时解决方案

感谢@funilrys 和How do I redirect all requests that contains a certain string to 404 in nginx?

现在 100% 有效

location /resources { expires 3h; add_header Cache-Control 'must-revalidate, proxy-revalidate, max-age=10800'; location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 3h; add_header Cache-Control 'must-revalidate, proxy-revalidate, max-age=10800'; } location ~* \.(pdf)$ { expires 30d; add_header Cache-Control 'must-revalidate, proxy-revalidate, max-age=2592000'; if ($request_uri ~ .*%.*) { return 301 https://example.com/resources/weather-documents/historical-rainfall-trends-south-africa_1921_2015.pdf; } if ($request_uri ~ .*[^\x00-\x7F]+.*) { return 301 https://example.com/resources/weather-documents/historical-rainfall-trends-south-africa_1921_2015.pdf; } }

【问题讨论】:

    标签: regex nginx nginx-location


    【解决方案1】:

    临时解决方案

    感谢@funilrys 和How do I redirect all requests that contains a certain string to 404 in nginx?

    现在 100% 有效

    location /resources { expires 3h; add_header Cache-Control 'must-revalidate, proxy-revalidate, max-age=10800'; location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 3h; add_header Cache-Control 'must-revalidate, proxy-revalidate, max-age=10800'; } location ~* \.(pdf)$ { expires 30d; add_header Cache-Control 'must-revalidate, proxy-revalidate, max-age=2592000'; if ($request_uri ~ .*%.*) { return 301 https://example.com/resources/weather-documents/historical-rainfall-trends-south-africa_1921_2015.pdf; } if ($request_uri ~ .*[^\x00-\x7F]+.*) { return 301 https://example.com/resources/weather-documents/historical-rainfall-trends-south-africa_1921_2015.pdf; } }

    【讨论】:

      【解决方案2】:

      你的解决方案很糟糕,让我告诉你为什么。

      现在,与此位置块匹配的每个请求都必须在提供服务之前针对两个 if 条件进行评估。

      任何匹配的请求都会被重定向到正确的 url,该 url 也匹配此位置块,因此现在您的服务器正在对这些 if 条件进行另外两次评估。

      只是为了好玩,您还让 Nginx 根据您的 if 条件评估对图像、css 和 js 文件的请求。它们都不匹配,因为您担心 pdf,但您仍然为请求处理增加了 200% 的额外开销。

      一个对 Nginx 更友好的解决方案实际上非常简单。

      Nginx 会按照位置指令在您的配置中列出的顺序进行正则表达式匹配,并选择第一个匹配块,因此如果此文件 url 将匹配您的任何其他正则表达式指令,那么您需要将此块放在这些位置之上:

      location ~* /historical-rainfall-trends-south-africa-1921([^_])*?2015\.pdf$ {
          return 301 https://example.com/resources/weather-documents/historical-rainfall-trends-south-africa_1921_2015.pdf;
      }
      

      刚刚在我的一台运行 Nginx 1.15.1 的服务器上对其进行了测试,效果很好。

      【讨论】:

      • 谢谢你 miknik 这更干净、更简单,我知道我的解决方案根本不是最好的,但它暂时有效。我完全理解 Nginx 中位置的顺序,我完全不喜欢正则表达式,只是不能完全确定这一点,但你做到了,所以我今天将把你的位置付诸实践,然后再回复你。非常感谢
      • 早上@miknik 我今天早上尝试了你的解决方案,但我没有成功,我把这个位置块放在不同的地方,试图找出它为什么不起作用但仍然没有成功。今天晚些时候将重新测试并回复您,有些东西出了问题,但我现在无法发现它,它一定是盯着我的脸。
      • 这个让我发疯,我什至把它移到了位置排序中可能的最高位置,但它不起作用:sob: 只给我 404 而不是重定向。明天我将不得不在一个新的测试站点上进行测试,然后慢慢追踪哪里出了问题。
      • 指令中的返回 URL 是否 100% 正确?您确定它不会将 301 返回到错误的位置吗?你的日志说什么?您是否在服务器级别设置了根指令?
      • 嗨@miknik 是的,301 是 100% 正确的,我尝试将你的位置声明放在任何地方,只是不断得到 404,但是当使用 if 语句时(现在修改块和临时解决方案更新)它仍然可以 100% 工作。我无法理解这一点。
      【解决方案3】:

      我不知道 Nginx 以及它处理正则表达式的方式,但是:

      • 您可以尝试匹配编码 URL 中的百分比:

        %+

      • 您可以尝试匹配编码 URL 中的特殊字符:

        (%([A-Z][0-9]|[0-9][A-Z]|[0-9]+|[A-Z]+))+

      • 您可以尝试匹配未编码 URL 中的非 ASCII 字符:

        [^\x00-\x7F]+

      证明:

      【讨论】:

      • 谢谢你,我会在早上试一试,然后报告
      • Nginx 使用 PCRE 正则表达式
      猜你喜欢
      • 2021-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多