【问题标题】:Mod_rewrite extract IP address from end of URL and pass to query string variableMod_rewrite 从 URL 末尾提取 IP 地址并传递给查询字符串变量
【发布时间】:2018-03-23 09:54:41
【问题描述】:

我正在尝试编写一个简单的地理定位功能,它将 URL 末尾的 IP 地址传递给查询字符串。

在我的 apache.conf 中,我有以下指令:

RewriteEngine On
RewriteBase /geo/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} .*/([0-9_._]+)/?$
RewriteRule .*  /lookup.php?ip=%1  [L,QSA]

所以我想知道网址:

https://example.com/geo/100.101.0.101  or
https://example.com/geo/100.101.0.101/

将ipv4地址发送到:

 https://example.com/lookup.php?ip=100.101.0.101

让它与 ipv6 一起工作也很棒。

【问题讨论】:

  • 你的规则有什么问题?
  • 它不工作。该规则应该有效吗?我收到 404 错误。
  • lookup.php 在哪里?是否在同一个geo/ 目录中?

标签: regex apache mod-rewrite url-rewriting


【解决方案1】:

您的重写并非 100% 准确

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# IPv4
RewriteCond %{REQUEST_URI} ^/?geo/([0-9\.]+)/?$ [NC,OR]
# IPv6
RewriteCond %{REQUEST_URI} ^/?geo/([0-9a-f:]+)/?$ [NC]
RewriteRule ^.*$  /lookup.php?ip=%1  [L,QSA]

解释:

RewriteBase /geo/ 仅在您这样做时才有意义,例如RewriteRule ^.*$ lookup.php?ip=%1 [L,QSA] 和 lookup.php 实际上在 http://example.com/geo/lookup.php 中

%{REQUEST_URI} 应以 geo/<ip> 开头,这取决于您的服务器是否包含前导 /。

IP 仅包括数字 (0-9)、a-f(仅 IPv6)和 . 或 :,具体取决于 IP 地址的版本(IPv4 或 IPv6)。

目前还可以发送格式无效的 IP 地址,例如, /geo/999..777.444 但我假设你会在你的应用程序中检查这个。 但是如果你有/geo/xx+666=765,那么它根本不会被重写。

如果你真的只想重写有效的 IP 地址而不是使用更复杂的 RegEx:

# IPv4 
RewriteCond %{REQUEST_URI} ^/?geo/(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/?$ [NC,OR]
# IPv6  
RewriteCond %{REQUEST_URI} ^/?geo/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/?$ [NC]

基于来自https://stackoverflow.com/a/17871737/5427950的正则表达式

我在 Ubuntu 16.04.03 LTS 服务器和 Apache 2.4.27 上测试了这个结果

【讨论】:

    猜你喜欢
    • 2012-05-11
    • 2017-11-15
    • 2012-06-25
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多