default
menu home
Icon library Sign up Login favorite_border message help_outline
Online notes - online bookmark

网络收藏夹网站开发过程中PHP正则表达式忘记使用非贪婪模式带来的一次教训

styleTags: All CSS html javascript php/other IT
by: fanshome  2023-06-09 13:43(UTC)

新版favinavi人性化网络收藏夹网站建设初期,还没有开始宣传,就发现访问量开始8小时内达到了大几千,有点喜出望外。可是再看看又发现不对,统计的关键页面的访问量少的可怜,那么访问量都是哪儿来的呢?

没办法,只能老老实实添加详细统计代码来企图发现问题。果然,详细分析后发现了2个重大问题:

1、异常流量主要来自垃圾蜘蛛爬网;

2、异常流量集中在登录页面“https://favinavi.com/login?o=xxx”。

这就奇了怪了,一个登录页面你个蜘蛛要重复爬几千次是几个意思?!

再仔细分析,发现其实每次垃圾蜘蛛访问的url其实不完全相同,参数o后面的内容非常花样繁多,不属于正常情况下应该出现的。

这里解释一下,参数o是为了记录用户登陆前所在页面,万一用户要干点什么的时候却登录超时了的话,一旦登录成功可以立即跳转到登录前的页面,这样做完全是为了用户能有更良好的体验。问题到底出在哪里呢?

最终分析发现,问题出在提取文件名的正则表达式上。

php代码:

$fn=preg_replace("/^(.*)\?.*$/","$1",$_SERVER['REQUEST_URI']);

其本意是想记录用户登录超时前所访问的页面,去掉问号后面不必要的参数,得到一个“纯净”的文件名,初看其实好像也没啥问题。但其实这个正则表达式是有个大问题的。因为登录前所访问页面的参数中是可能包含参数的,说得有点绕,就是uri中问号后面可能还有问号。虽然经过了urlencode,但问号本质上还是问号。那么问题就来了,上面的正则没有使用非贪婪匹配,就会匹配到最后一个问号,前面的$fn就会变成一个已经带了参数的乱七八糟的文件名,由于网站有多个地方需要处理这个纯净$fn,最后再加上原有的访问参数提交。不光是php,还有JavaScript参与,所以最后的结果是login后面的参数越变越多,越来越长,并且绕不出来。爬虫又不是人,会折腾几次发现不对就放弃,它不断地爬啊爬,每次都当成是爬到了一个新的链接,所以就继续爬喽...

这个bug解决起来其实很简单,把正则表达式括号里的内容改成非贪婪模式就对了:

$fn=preg_replace("/^(.*?)\?.*$/","$1",$_SERVER['REQUEST_URI']);

星号后面再跟一个问号,就成了非贪婪匹配,只留下第一个问号前面的内容,就是我想要的“纯净”的文件名了。

visibility 1849


- for heavy web user Online notes
adimg
logo Post a comment

captcha
Please check the captcha code
Cancel