一个系列网站从drupal 6升级到drupal 7后日志中发现大量报错,都是以前可以正常访问的网址现在找不到了,发现以前drupal 6中是这样的:
http://ut.mingluji.com/business_directory/Western_Heating_%2526_Air_Conditioning
在google搜索中也是上面这样的网址,但升级后以上访问成了404 not found,而用下面这样的网址可以访问:
http://ut.mingluji.com/business_directory/Western_Heating_%26_Air_Conditioning
对比发现少了一个25,为了兼容起来还需要在.htaccess中写一个Apache ReWrite规则来实现老网址301重定向跳转到新网址,按理说这个跳转非常简单的,但那个%2526的写法却总是不被apache识别,和同事尝试了好几个小时才最终搞定:
RewriteCond %{REQUEST_URI} ^(.*)\%26(.*)$ RewriteRule ^(.*)\%26(.*)$ $1\%26$2 [NE,L,R=301]
要点有两个:
- %百分号后面不需要也不能加25,否则就识别不出来了,只能写%26才可以识别出%2526;
- 替换结果中总是自动出现%25,直到加了NE(‘noescape|NE’,在输出中不对URI进行转义)才不会出现这个25
翻看以前的博客文章《Drupal的Pathauto模块生成带有单引号、双引号、反斜杠URL问题及解决》、《Drupal_7的URL中+加号、&符号的编码问题及解决》,当时也遇到网址中特殊符号转义的问题,通过修改drupal 6的核心文件来解决,但这样可能留下隐患,影响drupal 6的小版本升级以及到drupal 7的大版本升级。
另外还找到一篇《Apache中设置屏蔽IP地址和URL网址来禁止采集》,看到.htaccess中有这样写的:
RewriteCond %{HTTP_HOST} ^can\.bizdirlib\.com(.*)$ RewriteCond %{REQUEST_URI} ^\/business_directory\/S\_\%26\_J(.*)$ RewriteRule .* - [F,L]
其中也包含%26,我记得当时是为了屏蔽反复抓取某个网址采取的屏蔽措施,当时也是花了好些时间来改这个正则才实现的,只是时间太久,忘记以前的情况了,当时应该也是为了屏蔽%2526这样的。
2016年3月28日补充:如果手机版中带有%26网址的页面报错,可以这样改:
# drupal 6 to drupal 7 from %2526 to %26 RewriteCond %{REQUEST_URI} ^\/m\/ RewriteCond %{REQUEST_URI} ^(.*)\&(.*)$ RewriteRule ^(.*)$ %1\%2526%2 [NE,L] RewriteCond %{REQUEST_URI} !^\/m\/ RewriteCond %{REQUEST_URI} ^(.*)\%26(.*)$ RewriteRule ^(.*)\%26(.*)$ $1\%26$2 [NE,L,R=301]
如果网址中带有两个、多个%26的情况,在手机版中还需要这样处理:
# drupal 6 to drupal 7 from %2526 to %26 RewriteCond %{REQUEST_URI} ^\/m\/ RewriteCond %{REQUEST_URI} ^(.*)\&(.*)\&(.*)\&(.*)$ RewriteRule ^(.*)$ %1\%2526%2\%2526%3\%2526%4 [NE,L] RewriteCond %{REQUEST_URI} ^\/m\/ RewriteCond %{REQUEST_URI} ^(.*)\&(.*)\&(.*)$ RewriteRule ^(.*)$ %1\%2526%2\%2526%3 [NE,L] RewriteCond %{REQUEST_URI} ^\/m\/ RewriteCond %{REQUEST_URI} ^(.*)\&(.*)$ RewriteRule ^(.*)$ %1\%2526%2 [NE,L] RewriteCond %{REQUEST_URI} !^\/m\/ RewriteCond %{REQUEST_URI} ^(.*)\%26(.*)$ RewriteRule ^(.*)\%26(.*)$ $1\%26$2 [NE,L,R=301]
评论