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>
演示
<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
要转义四次:
- URL-转义到
x%20%E2%80%93%20y
- JS-转义为
x%20%E2%80%93%20y
(这次没有变化,因为这个值中没有JS-特殊字符)
- URL-逃到
x%2520%25E2%2580%2593%2520y
- 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
我有这个网站:
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>
演示
<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
要转义四次:
- URL-转义到
x%20%E2%80%93%20y
- JS-转义为
x%20%E2%80%93%20y
(这次没有变化,因为这个值中没有JS-特殊字符) - URL-逃到
x%2520%25E2%2580%2593%2520y
- 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.