我们在网络应用中有一个菜单,使用<a>
标记在主框架中加载页面。
菜单中的典型项目如下:
<a target="mainframe" href="/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3¶m3=val4">Menu Item 1</a>
我们需要在请求链接之前添加一些JavaScript验证,因此我将其更改为:
<a target="mainframe" href="javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3¶m3=val4')">Menu Item 1</a>
(我知道链接中的javascript:function
是不好的做法,但我们使用第三方库生成菜单,因此我无法更改此部分代码)
Servlet1期望:
参数1 = 'VAL1'
参数2 = 'servlet2?s2p1 = VAL2%26s2p2 = VAL3'
参数3 = 'VAL4'
Servlet1然后转发到param2的值,因此Servlet2期望:
s2p1 = 'val2的'
s2p2 ='val3'
然而,当我在验证函数中放置一个alert
来检查传入的内容时:
function validate(href) {
alert(href);
...validation code...
}
它给予:
/ servlet1?param1 = val1&amp; parma2 = servlet2?s2p1 = val2 **&amp; ** s2p2 = val3&amp; param3 = val4(注意上面函数调用中&
的粗体%26
< / p>
%26
在传递给JS函数时会转换为&
,这在请求转发到Servlet2
之前通常不会发生。由于%26
已更改为&
,s2p2
请求参数会被servlet1
而非servlet2
选中。
基本上我的问题是为什么%26
此时只是将&
作为参数从href
属性传递给onClick="validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3¶m3=val4')"
,如果你这样做{ {1}}
它会像你期望的那样保持%26
吗?
答案 0 :(得分:8)
<a target="mainframe" href="javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3¶m3=val4')">Menu Item 1</a>
Urgh。您有一个嵌入在URL中的URL,所有这些都嵌入在另一个URL中!这是逃避人类思维应对的太多层次。这个:
javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3¶m3=val4')
本身就是一个网址。虽然是javascript:
伪URL,但您永远不应该使用它。它被解码为JavaScript命令:
validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2&s2p2=val3¶m3=val4')
此时你已经失去了%26。现在,当您将其用作URL本身时,它将失败。
通过将脚本移动到JavaScript块(或外部脚本)而不是HTML属性来避免多重编码问题:
<a target="mainframe" class="validateme" href="/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4">Menu Item 1</a>
(此处还请注意&符号的必要HTML转义。)然后从脚本执行:
// find 'validateme' links and add event handler
//
for (var i= document.links; i-->0;)
if (document.links[i].className==='validateme')
document.links[i].onclick= validate;
然后在验证功能中,只需返回true
,如果一切正常并且您希望关注该链接,或false
停止该链接。
答案 1 :(得分:7)
不,%26
被(正确地)解释为&amp;当HTML文件首次读入浏览器时,而不是传入JavaScript函数时。如果你想要字符序列的字符“百分之二六”,那么你必须将其编码为%2526
。
答案 2 :(得分:0)
javascript:
协议仍被视为有效网址,因此浏览器正在对其进行正确编码。在Javascript中解码它很容易......
alert(decodeURIComponent(href));