目錄
HTML實體編碼
URL編碼
Unicode編碼
解析層次邏輯
為什么<script></script>不可以編碼符號
為什么不能編碼JavaScript:協議
為什么RCDATA標簽中的都會被解析成文本
為什么HTML編碼了<>無法執行
HTML實體編碼
通過特殊語法(<、>)表示保留字符,防止和HTML標簽沖突。
URL編碼
URL地址欄編碼,表現形式為%開頭
Unicode編碼
JavaScript本身支持的編解碼方式,表現形式為\u000a等。
解析層次邏輯
HTML實體編碼-->URLcode-->Unicode編碼
注:三者有自己的解析器,是一個傳遞調用過程。
具體案例分析
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>url編碼了JavaScript:協議,不可以<br><a href="javascript:%61%6c%65%72%74%28%32%29">222</a>可以,JavaScript:被實體編碼,但是HTML解析在url前,所以可以成功執行<br><a href="javascript%3aalert(3)"></a>編碼了協議符號,不可以<br><div><img src=x onerror=alert(4)></div>不可以,編碼了<>,雖然會解析,但是被當作文本,不回進入標簽開始狀態<br><textarea><script>alert(5)</script></textarea>不可以,rcdata元素,里的標簽會被當作文本<br><textarea><script>alert(6)</script></textarea>不可以,同第5條<br><button onclick="confirm('7');">Button</button>可以執行,HTML實體編碼單引號會先解析,傳遞給JavaScript時就可以執行<br><button onclick="confirm('8\u0027);">Button</button>不可以,Unicode編碼單引號,無法解析,JavaScript并不會解析<br><script>alert(9);</script>不可以,script標簽內默認是JavaScript代碼,HTML不會解析,JavaScript不認識HTML編碼后的內容<br><script>\u0061\u006c\u0065\u0072\u0074(10);</script>可以,JavaScript可以解析Unicode編碼<br><script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029;</script>不可以,JavaScript不可以編碼符號<br><script>\u0061\u006c\u0065\u0072\u0074(\u0031\u0032)</script>不可以,因為解析返回是字符串,字符串12需要引號包裹,所以這里是有一個語法錯誤<br><script>alert(\u002713\u0027)</script>不可以,編碼符號JavaScript不認識<br><script>alert('14')\u000a</script>不可以,可以換行,但是被Unicode編碼了就不可以了<br><a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)">15</a>可以,遵守了解碼順序,可以執行</body>
</html>
為什么<script></script>不可以編碼符號
<script></script>屬于“原始文本”元素,在塊內的字符引用并不會被解析和解碼,這是為什么呢?
字符串中:當Unicode轉義序列存在于字符串中時,它只會被解釋為正規字符,而不是單引號,雙引號或者換行符這些能夠打破字符串上下文的字符。這項內容清楚地寫在ECMAScript中。因此,Unicode轉義序列將永遠不會破環字符串上下文,因為它們只能被解釋成字符串常量。
為什么不能編碼JavaScript:協議
URL解析器只認識ascii類型,一旦編碼URL解析器不認識就是一個無協議狀態,不會讓JavaScript解析器來解析,自然就執行不了。2為什么能執行,因為HTML解析器的優先級在URL解析器之前,先解析成了JavaScript:協議,URL解析器自然就認識了,交給JavaScript解析器處理執行。
為什么RCDATA標簽中的都會被解析成文本
RCDATA中有<textarea>,<title>標簽,在HTML解析器解析RCDATA 標簽時,進入RCDATA狀態,在這個狀態能被識別為標簽的只有</textarea>,</title>。這就解釋了為什么RCDATA中的任意代碼無法執行。
為什么HTML編碼了<>無法執行
當HTML解析器遇到<時后面沒有/,就認為是標簽的開始,進入標簽開始狀態。那為什么不行呢?因為當HTML解析了<>的編碼后,進入不了標簽開始狀態,不是標簽,自然無法執行。