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

Chr*_*s R 4 html javascript

我们在Web应用程序中有一个菜单,它使用<a>标签在主框架中加载页面.

菜单中的典型项目如下:

<a target="mainframe" href="/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4">Menu Item 1</a>
Run Code Online (Sandbox Code Playgroud)

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

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

(我知道javascript:function在链接中是不好的做法,但我们使用第三方库来生成菜单,所以我无法更改这部分代码)

Servlet1期望:
param1 ='
val1'param2 ='servlet2?s2p1 = val2%26s2p2 =
val3'param3 ='val4'

Servlet1然后转发到param2的值,因此Servlet2期望:
s2p1 ='
val2's2p2 ='val3'

但是,当我alert在我的验证函数中放入一个检查传入的内容时:

function validate(href) {
    alert(href);

    ...validation code...
}
Run Code Online (Sandbox Code Playgroud)

它给:
?/ servlet1参数1 = VAL1&parma2 = servlet2 s2p1 = val2的****&= S2P2 VAL3&参数3 = VAL4(注意粗体&这是%26在上述的函数调用)

%26被转换&为传递给JS函数的时间,这通常不会发生,直到请求被转发到Servlet2.因为%26已经更改为&s2p2请求参数得到由捡起servlet1来代替servlet2.

基本上我的问题是为什么在这一点上将%26get转换为a &只是将它作为参数从href属性传递给函数,如果你这样做 就像你期望的那样onClick="validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4')"
保持%26

bob*_*nce 8

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

Urgh.您有一个嵌入在URL中的URL,所有这些都嵌入在另一个URL中!对于人类的大脑来说,这是太多的逃避.这:

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

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

validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2&s2p2=val3&param3=val4')
Run Code Online (Sandbox Code Playgroud)

此时你已经失去了%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>
Run Code Online (Sandbox Code Playgroud)

(这里还要注意&符号的必要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;
Run Code Online (Sandbox Code Playgroud)

然后在您的验证函数中,只需返回,true如果一切正常并且您希望遵循该链接,或者false将其停止.


Jon*_*erg 7

不,%26当首次将HTML文件读入浏览器时(而不是将其传递给JavaScript函数时),(正确)解释为&。如果您想要字符的文字序列“百分之二六”,则必须将其编码为%2526