Perl 5.18.2的CGI start_html生成重复rel属性,求修复方案
修复CGI 3.63中start_html方法导致的标签重复rel属性问题
问题复现
当给CGI的start_html方法配置复杂参数(比如同时指定-style数组、-javascript、-meta等)时,会出现通过-style传入的CSS对应的<link>标签重复rel属性的问题。比如示例代码:
use CGI qw(:standard); print start_html( -title => '测试页面', -style => [ { -src => '/css/main.css', -media => 'screen' }, { -src => '/css/print.css', -media => 'print', -rel => 'stylesheet alternate' } ], -javascript => ['/js/main.js'], -meta => { 'viewport' => 'width=device-width' } );
输出的<link>标签会变成:
<link rel="stylesheet" href="/css/print.css" media="print" rel="stylesheet alternate" />
这是CGI 3.63版本的已知bug。
可行修复方案
1. 手动输出标签替代-style参数
直接绕过start_html的-style处理逻辑,在生成页面头部后手动添加正确的CSS链接:
use CGI qw(:standard); # 只传递非-style的参数给start_html print start_html( -title => '测试页面', -javascript => ['/js/main.js'], -meta => { 'viewport' => 'width=device-width' } ); # 手动构造正确的<link>标签 print qq(<link rel="stylesheet" href="/css/main.css" media="screen" />\n); print qq(<link rel="stylesheet alternate" href="/css/print.css" media="print" />\n);
这种方式完全由你控制<link>标签的属性,彻底避免CGI内部的拼接错误。
2. 给CGI模块打临时补丁
找到系统中CGI.pm文件的位置(可以通过perldoc -l CGI命令查找),定位到处理-style参数的代码段。通常会有一段默认设置rel="stylesheet"的逻辑,比如:
$rel = 'stylesheet' unless defined $rel;
把这段代码修改为:
$rel = 'stylesheet' unless defined $rel && $rel ne '';
这样当你手动指定-rel参数时,CGI就不会再默认添加rel="stylesheet",也就不会出现重复属性。修改后保存文件,重启你的应用即可生效。注意:这个补丁是临时的,后续升级CGI版本后需要重新检查。
3. 升级CGI到修复后的版本
查看CGI模块的更新日志,确认3.63之后的版本(比如3.64及以上)是否修复了这个bug。如果已经修复,直接通过CPAN升级:
cpan CGI
这是最稳妥的解决方案,还能顺带修复其他旧版本可能存在的问题。
内容的提问来源于stack exchange,提问作者U. Windl
相关产品推荐
相关产品推荐

