为什么%26会被解码为&当从链接作为参数传递给JavaScript函数时?

时间:2009-10-30 15:58:26

标签: javascript html

我们在网络应用中有一个菜单,使用<a>标记在主框架中加载页面。

菜单中的典型项目如下:

<a target="mainframe" href="/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4">Menu Item 1</a>

我们需要在请求链接之前添加一些JavaScript验证,因此我将其更改为:

<a target="mainframe" href="javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=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&param3=val4')",如果你这样做{ {1}}
它会像你期望的那样保持%26吗?

3 个答案:

答案 0 :(得分:8)

<a target="mainframe" href="javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4')">Menu Item 1</a>

Urgh。您有一个嵌入在URL中的URL,所有这些都嵌入在另一个URL中!这是逃避人类思维应对的太多层次。这个:

javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4')

本身就是一个网址。虽然是javascript:伪URL,但您永远不应该使用它。它被解码为JavaScript命令:

validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2&s2p2=val3&param3=val4')

此时你已经失去了%26。现在,当您将其用作URL本身时,它将失败。

通过将脚本移动到JavaScript块(或外部脚本)而不是HTML属性来避免多重编码问题:

<a target="mainframe" class="validateme" href="/servlet1?param1=val1&amp;parma2=servlet2?s2p1=val2%26s2p2=val3&amp;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));