我试图编写一个简单的地理位置,将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一起使用也是一个超级好的。
答案 0 :(得分:0)
您的重写不是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
的RegEx我用Apache 2.4.27测试了这个肯定的Ubuntu 16.04.03 LTS服务器