我正在使用CGI转义方法来转义href链接标记的url。 没有escape()调用,链接在我的浏览器中工作正常,因为它足够聪明,可以将空格转换为URL的一部分。
我的cgi脚本有这个
print $outhtml->a({href=>$outhtml->escape($wavURL)}, $outhtml->escapeHTML($exportFilename));
其中$outhtml
是CGI对象,wav网址是http://localhost/downloads/My File.mp3
使用转义,输出为:
<a href="http%3A%2F%2Flocalhost%2Fdownloads%2FMy%20File.mp3">My File</a>
这对我来说没问题,但是chrome将此视为相对链接,因此当我点击它或复制链接地址时,它会附加localhost / cgi-bin,给出格式错误的地址,如下所示:
http://localhost/cgi-bin/http%3A%2F%2Flocalhost%2Fdownloads%2FMy%20File.mp3
我在原始网址中没有前导'http://'
的情况下尝试过此操作,并且会产生相同的不良行为。我也尝试使用没有主机名的绝对URL,如/downloads/My File.mp3
,但这也有相同的行为。我在chrome和firefox上测试了这个,结果都是一样的。
我也尝试过URI :: Escape,但它做了同样的事情。
我做错了什么?
答案 0 :(得分:3)
您应该只转义CGI参数的值,而不是整个URL。例如:
http://localhost/cgi-bin/get_file_by_url.pl?where=http%3A%2F%2Flocalhost%2Fdownloads%2FMy%20File.mp3
必须转义where
的值。 URI模块可以帮助您。
use URI;
my $myurl = URI->new('http://localhost/downloads/My File.mp3');
print $myurl->as_string, "\n";
# http://localhost/downloads/My%20File.mp3
答案 1 :(得分:0)
我只想转义文件名。
答案 2 :(得分:0)
因为escape
转换了URL中具有特殊含义的任何字符,因此可以将其用作数据。如果您输入完整的网址,那么您会将//
(将方案与主机分开)转换为%2F%2F
(两个斜杠字符)。
答案 3 :(得分:0)
一个非常老的问题,但没有真正的真实答案。
正如您所指出的那样,对于旧版本的浏览器来说,不逃避任何操作都可能会失败。转义URL的 some 不会破坏较旧的浏览器,因为浏览器(旧的和新的)按原样使用该链接。
它首先查找以“(protocol):”开头的URL,如果找不到,则默认为“ http:”。然后,它查找// servername /,如果找不到,则默认为当前页面所在的服务器。 ':'和'//'的匹配为文字,浏览器不会对此URL进行转义。
实际上,URL的转义只有在到达处理URL的程序时才发生。如果URL是用于CGI程序的,则该CGI程序将接收到整个转义的URL,并且要由CGI程序对其进行转义。
但是要达到这一点,协议,服务器名称和CGI程序以及特殊字符都不得转义。 转义不是