window.open UTF-8 问题

window.open UTF-8 Issue

我有这个网站:

http://a.b/x – y

破折号是非 ASCII \u2013 或 UTF-8 中的 %E2%80%93。

以下使用 UTF-8 的 link 可以正常工作:

<a href="http://a.b/x%20%E2%80%93%20y" target="_blank">True Link</a>

但是用 window.open() 和完全相同的 URL 编写脚本会得到 404:

<a href="javascript:void(window.open( 'http://a.b/x%20%E2%80%93%20y','_blank','top=10,left=10,height=900,width=1500,resizable=yes'))">Raw JS Link</a>

查看错误页面上的属性以查看结果 URL 我注意到扩展破折号被替换为: ??

如果我替换扩展破折号,并且只有扩展破折号为“\u2013”​​,link 可以正常工作:

<a href="javascript:void(window.open( 'http://a.b/x%20\u2013%20y','_blank','top=10,left=10,height=900,width=1500,resizable=yes'))">Modified JS Link</a>

并且生成的 URL 似乎已将扩展破折号重新编码回 UTF-8。

考虑到这一点,我尝试解码 UTF-8 编码并仅对 space 重新编码,但失败并出现与之前相同的错误:

<a href="javascript:void(window.open( decodeURIComponent('http://a.b/x%20%E2%80%93%20y').split(' ').join('%20'),'_blank','top=10,left=10,height=900,width=1500,resizable=yes'))">Raw JS Link</a>

我怀疑 window.open() 出于某种原因正在破坏 URL。

然后我继续尝试了一堆不同的想法和解码/编码的组合,甚至将 escpae()/unescape() 拖回使用,但无济于事。

window.open 的原因是我只能控制 HREF 属性的内容。在这种情况下,它是 "Go to URL" 操作中的 SSRS 表达式,SSRS UTF-8 对某些字符进行编码,因此即使使用上面的 split(' ') 我实际上也必须使用 split(String.fromCharCode(32 )). 但是,我已将所有内容剥离到一个简单的 HTML 页面中,这是我进行分析的地方。

PS:IE8,尽管用户群是 IE8+ PSS:添加了遗漏的引号。 PSS:看起来这可能是 IE8 特有的问题。

您上一个示例中的单引号放错了位置,此外,不需要 .split(' ').join('%20'),因为它会产生错误。

<a href="javascript:void(window.open( decodeURIComponent('https://www.google.pt/search?q=x%20%E2%80%93%20y'),'_blank','top=10,left=10,height=900,width=1500,resizable=yes'))">Raw JS Link</a>

演示

http://jsfiddle.net/bf2703ah/1/

<a href="javascript:void(window.open('http://a.b/...component...

所以这里有多个嵌套的转义上下文。您正在将文本注入:

  • URL 的一个组件(需要 URL-转义),在
  • a JavaScript 字符串文字(需要 JS 转义),在
  • a javascript: pseudo-URL (需要 URL-escaping), inside
  • 一个HTML属性值(需要HTML-转义)

所以值x – y要转​​义四次:

  1. URL-转义到x%20%E2%80%93%20y
  2. JS-转义为x%20%E2%80%93%20y(这次没有变化,因为这个值中没有JS-特殊字符)
  3. URL-逃到x%2520%25E2%2580%2593%2520y
  4. HTML-转义为x%2520%25E2%2580%2593%2520y(这次没有变化,因为这个值中没有HTML-特殊字符)。

需要转义的嵌套语法非常非常难以正确处理。通常你不应该使用 javascript: URLs:除了成为多重转义的噩梦之外,它们对可用性和可访问性也很糟糕。

避免注入嵌套代码。对于在新的 window 中打开的 link 更好的模式(如果你绝对必须)是将真正的 URL 放在 href 中,这样它就能正确响应中间-click 和其他 link 功能可见性,然后从 JS 读取该 href,例如:

<a href="http://a.b/x%20%E2%80%93%20y" onclick="window.open(this.href, ...options...); return false;"

(return-false 防止在 window 打开后跟随 link。)还可以考虑将 JS 代码分解成一个单独的脚本,该脚本绑定到所有适当的links 自动(例如通过 class 属性)所以你不必在你的 HTML.

中有内联 JavaScript