到目前为止我的发现:
首先,有编写有效 HTML 属性值的规则:但这里的标准只要求(如果属性值用引号括起来)任意 CDATA(实际上是 %URI,但 HTML 本身并没有强加额外的其级别的验证:任何 CDATA 都将验证)。
一些例子:
<a href="javascript:alert('Hi!')"> (1)
<a href="javascript:if(a > b && 1 < 0) alert( b ? 'hi' : 'bye')"> (2)
<a href="javascript:if(a>b &&& 1 < 0) alert( b ? 'hi' : 'bye')"> (3)
示例 (1) 有效。但示例 (2) 也是有效的 HTML 4.01 Strict。为了使它成为有效的 XHTML,我们只需要转义 XML 特殊字符 < > &(示例 3 是有效的 XHTML 1.0 Strict)。
现在,示例 (2) 是有效的 javascript: URI 吗?我不确定,但我会说不是。
来自RFC 2396:URI 受到一些附加限制,特别是通过%xx 序列的转义/取消转义。有些字符总是被禁止的:
其中空格和{}#。
RFC 还定义了opaque URIs 的子集:那些没有分层组件,并且分隔字符没有特殊含义的子集(例如,它们没有“查询字符串”,因此?可以用作任何非特殊字符)。我认为javascript: URI 应该被考虑在内。
这意味着javascript: URI 的“正文”内的有效字符是
a-zA-Z0-9
_|. !~*'();?:@&=+$,/-
%hh : (escape sequence, with two hexadecimal digits)
附加限制不能以/ 开头。
这仍然遗漏了一些“重要”的 ASCII 字符,例如
{}#[]<>^\
还有%(因为它用于转义序列)、双引号" 和(最重要的)所有空格。
在某些方面,这似乎相当宽松:重要的是要注意+ 是有效的(因此在解码时不应将其“转义”为空格)。
但在其他方面,它似乎过于严格。大括号和方括号,特别是:我知道它们通常不转义使用,浏览器没有问题。
那么空间呢?作为大括号,RFC 不允许使用它们,但我认为这种 URI 没有问题。但是,我看到在大多数小书签中,它们被转义为“%20”。对此有任何(经验或理论)解释吗?
我仍然不知道是否有一些标准函数可以使这种转义/取消转义(在主流语言中)或一些示例代码。