代码之家  ›  专栏  ›  技术社区  ›  Chris R

当从链接作为参数传递给javascript函数时,为什么要将%26解码为&

  •  4
  • Chris R  · 技术社区  · 16 年前

    我们有一个菜单输入输出网络应用程序 <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预期:
    PARAM1=“VAL1”
    param2='servlet2?s2p1=val2%26s2p2=val3'
    PARAM3=’VAL4’

    然后servlet1转发到参数2的值,因此servlet2期望:
    S2P1=“Val2”
    s2p2='val3'

    但是当我把 alert 在我的validate函数中检查传入的内容:

    function validate(href) {
        alert(href);
    
        ...validation code...
    }
    

    它给予:
    Servel1?参数1=val1&parma2=servlet2?s2p1=val2**&**s2p2=val3&param3=val4(注意粗体 & 那是 %26 在上述函数调用中)

    这个 % 26 正在转换为 & 当它被传递到JS函数时,通常在将请求转发到 Servlet2 . 因为 %26 已更改为 & 这个 s2p2 请求参数由获取 servlet1 而不是 servlet2 .

    基本上我的问题是为什么 % 26 转换为 & 此时,只需将它作为参数传递给函数, href 属性 onClick="validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4')"
    它依旧 % 26 如你所料?

    3 回复  |  直到 11 年前
        1
  •  8
  •   bobince    16 年前
    <a target="mainframe" href="javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4')">Menu Item 1</a>
    

    呃。您有一个URL,嵌入在一个URL中,全部嵌入在另一个URL中!对于人类来说,逃避的程度太多了。这是:

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

    本身就是一个URL。尽管是 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;
    

    然后在validate函数中只返回 true 如果一切正常,并且您希望跟踪链接,或者 false 停止它。

        2
  •  4
  •   Jonathan Feinberg    16 年前

    不, %26 在HTML文件首次被读取到浏览器中时被(正确地)解释为&而不是在传递到javascript函数中时。如果需要字符“percent two six”的文字序列,则必须将其编码为 %2526 .

        3
  •  0
  •   Josh Stodola    16 年前

    这个 javascript: 协议仍然被视为有效的URL,因此浏览器正在对其进行正确编码。在你的javascript中很容易解码…

    alert(decodeURIComponent(href));