HTACCESS:使用BrowserMatchNoCase拦截多版本过时浏览器(Chrome/Firefox)的规则优化问询
首先得给你澄清一个关键误区——你之前写的规则其实并不是按版本数值范围来匹配的,这也是新版本(100+)被误拦截的核心原因!
你原来写的[17.0.0.0-86.0.0.0]是正则里的「字符类」写法,它的作用是匹配任意一个属于这个集合的单个字符:比如1、7、.、0,以及ASCII码在0-8之间的字符(也就是数字0到8)、6等等。简单说,这个规则其实是匹配Chrome/后面跟着任意0-8的数字或者.、1、6、7这些字符,和你想的「17到86版本范围」完全不是一回事——之前能"完美运行"只是巧合,因为旧版本的Chrome/Firefox主版本号开头都是1-8的数字,而100版本开头是1,第二个字符是0,刚好落在这个字符类里,所以被误判成bad_bots了。
不过别担心,我们可以用正则的数值范围匹配来实现你的需求:拦截版本号小于87的Chrome和Firefox,同时放过100及以上的版本,而且完全可以继续用BrowserMatchNoCase指令。
正确的规则写法
Chrome的拦截规则
要精准匹配主版本号小于87.0.0.0的Chrome,正则需要覆盖两种情况:
- 主版本号是10到79之间的(比如17.x到79.x)
- 主版本号是80到86之间的
对应的BrowserMatchNoCase规则:
BrowserMatchNoCase "^Chrome/(?:[1-7]\d|8[0-6])\." bad_bots
Firefox的拦截规则
同理,匹配主版本号小于87.0的Firefox:
BrowserMatchNoCase "^Firefox/(?:[1-7]\d|8[0-6])\." bad_bots
简单解释下正则逻辑
^:匹配User-Agent字符串的开头,避免误匹配其他包含"Chrome/"或"Firefox/"的奇怪UA(?:...):非捕获分组,用来把两个匹配规则打包在一起,不额外生成捕获组[1-7]\d:匹配10到79之间的数字(第一位是1-7,第二位是任意数字)8[0-6]:匹配80到86之间的数字\.:匹配版本号里的点,确保我们匹配的是完整的主版本号(比如不会误匹配Chrome/8这种不规范的UA)
这样写之后,只会拦截主版本号在10-86之间的浏览器,100及以上的版本会自动被放过,你之前加的那些例外规则就可以删掉了。
快速验证
你可以对着这些UA测试效果:
Chrome/86.0.4240.198:会被标记为bad_bots(符合预期)Chrome/87.0.4280.88:不会被标记(符合预期)Chrome/100.0.4896.127:不会被标记(符合预期)Firefox/86.0:会被标记(符合预期)Firefox/100.0:不会被标记(符合预期)
后续调整提示
如果之后需要修改拦截范围(比如要拦截到99版本),只需要调整正则里的数字就行。比如要拦截Chrome版本小于100的,规则可以改成:
BrowserMatchNoCase "^Chrome/(?:[1-9]\d?|99)\." bad_bots
这个正则会匹配1到99之间的主版本号,自动放过100及以上的版本。
内容的提问来源于stack exchange,提问作者JSSSX

