HTML解析以及编码总结

HTML解析

一个HTML解析器作为一个状态机,它从输入流中获取字符并按照转换规则转换到另一种状态。在解析过程中,任何时候它只要遇到一个’<‘符号(后面没有跟’/'符号)就会进入“标签开始状态(Tag open state)”。然后转变到“标签名状态(Tag name state)”,“前属性名状态(before attribute name state)”…最后进入“数据状态(Data state)”并释放当前标签的token。当解析器处于“数据状态(Data state)”时,它会继续解析,每当发现一个完整的标签,就会释放出一个token。
字符实体
字符实体是一个转义序列,它定义了一般无法在文本内容中输入的单个字符或符号。一个字符实体以一个&符号开始,后面跟着一个预定义的实体的名称,或是一个#符号以及字符的十进制数字。

HTML字符实体
在HTML中,某些字符是预留的。例如在HTML中不能使用“<”或“>”,这是因为浏览器可能误认为它们是标签的开始或结束。如果希望正确地显示预留字符,就需要在HTML中使用对应的字符实体。一个HTML字符实体描述如下:

字符引用
字符引用包括“字符值引用”和“字符实体引用”。在上述HTML例子中,‘<‘对应的字符值引用为’<’,对应的字符实体引用为‘<’。字符实体引用也被叫做“实体引用”或“实体”。)

现在你大概会明白为什么我们要转义“<”、“>”、“'” (单引号)和“"” (双引号)字符了。

这里要提一下RCDATA的概念。要了解什么是RCDATA,我们先要了解另一个概念。在HTML中有五类元素:

1.空元素(Void elements),如<area>,<br>,<base>等等
2.原始文本元素(Raw text elements),有<script><style>
3.CDATA元素(RCDATA elements),有<textarea><title>
4.外部元素(Foreign elements),例如MathML命名空间或者SVG命名空间的元素
5.基本元素(Normal elements),即除了以上4种元素以外的元素
五类元素的区别如下:

1.空元素,不能容纳任何内容(因为它们没有闭合标签,没有内容能够放在开始标签和闭合标签中间)。
2.原始文本元素,可以容纳文本。
3.RCDATA元素,可以容纳文本和字符引用。
4.外部元素,可以容纳文本、字符引用、CDATA段、其他元素和注释
5.基本元素,可以容纳文本、字符引用、其他元素和注释

如果我们回头看HTML解析器的规则,其中有一种可以容纳字符引用的情况是“RCDATA状态中的字符引用”。这意味着在<textarea><title>标签中的字符引用会被HTML解析器解码。这里要再提醒一次,在解析这些字符引用的过程中不会进入“标签开始状态”。,所以只能对HTML编码进行解码打印出文本,但不会执行解码后相应的字符引用。

另外,对RCDATA有个特殊的情况。在浏览器解析RCDATA元素的过程中,解析器会进入“RCDATA状态”。在这个状态中,如果遇到“<”字符,它会转换到“RCDATA小于号状态”。如果“<”字符后没有紧跟着“/”和对应的标签名,解析器会转换回“RCDATA状态”。这意味着在RCDATA元素标签的内容中(例如<textarea><title>的内容中),唯一能够被解析器认做是标签的就是“</textarea>”或者“</title>”
因此,在“<textarea>”和“<title>”的内容中不会创建标签,就不会有脚本能够执行。

解码案例

1.<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>
1无法弹窗,不能对协议类型进行任何的编码操作,不然URL解析器会认为它无类型(即被编码的javascript:),所以导致解码失败,不会被执行。

2.<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:%61%6c%65%72%74%28%32%29">
1先HTML解码,得到

<a href="javascript:%61%6c%65%72%74%28%32%29">

href中为URL,URL模块可识别为javascript协议,进行URL解码,得到

<a href="javascript:alert(2)">

由于是javascript协议,解码完给JS模块处理,于是被执行

3.<a href="javascript%3aalert(3)"></a>

1和第一题一样url编码不能编码协议,所以导致解码失败,不会被执行。

4.<div>&#60;img src=x onerror=alert(4)&#62;</div>

<img src=x onerror=alert(4)>

从HTML解析机制看,在读取

之后进入数据状态,<会被HTML解码,但不会进入标签开始状态,只是将<文本打印出来,所以就不会创建img元素,也就不会执行。

5.<script>alert(5)</script>
1
因为在RCDATA元素中唯一能够被解析器认做是标签的就是“”或者“”。所有其他的元素都会将当成文本直接打印,不会执行。

6.
和第五题同类型所有其他的元素都会将当成文本直接打印,不会执行。

7.Button
这里onclick中为标签的属性值(类比2中的href),会被HTML解码,得到
Button
所以可以直接执行

8.<button onclick="confirm('8\u0027);">Button</button>
因为在JS中unicode解析只能解析字符串和标识符,而单引号双引号圆括号这些会影响字符串上下文的符号将不能被unicode编码。而这一题编码的是单引号,所以JS执行失败。

9.<script>&#97;&#108;&#101;&#114;&#116&#40;&#57;&#41;&#59</script>
因为

10.<script>\u0061\u006c\u0065\u0072\u0074(10);</script>
因为没有编码符号,函数名alert属于标识符,所以直接将unicode编码直接解码,顺利被JS执行。

11.<script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>
由于编码了圆括号,所以导致JS执行失败。

12.<script>\u0061\u006c\u0065\u0072\u0074(\u0031\u0032)</script>
这里\u0031\u0032在解码的时候会被解码为字符串12,注意是字符串,不是数字,文字显然是需要引号的,JS执行失败

13.<script>alert('13\u0027)</script>
与上面第八题同类型,JSunicode编码不能编码符号。

14.<script>alert('14\u000a')</script>

因为\u000a在JavaScript里是换行,就是\n,所以代码会直接执行,但不会打破字符串上下文,所以正常执行JS代码。

15

 <a
href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x31;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x36;&#x33;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x35;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x32;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x34;&#x28;&#x31;&#x35;&#x29;"></a>

先HTML解码,得到

<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)"></a>

在href中由URL模块处理,解码得到

javascript:\u0061\u006c\u0065\u0072\u0074(15)

识别JS协议,然后由JS模块处理,解码得到

javascript:alert(15)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当 Servlet 处理完请求后生成的响应内容通常是动态生成的,它可能包含 HTML、CSS、JavaScript 或其他类型的数据。这个响应内容最终会被发送给客户端浏览器,并由浏览器解析和渲染成可视化的网页。 面是 Servlet 响应生成 HTML 的一般流程: 1. 创建响应对象:在 Servlet 中,可以通过 `HttpServletResponse` 对象来创建和设置响应内容。 2. 设置响应类型和字符编码:通过 `setContentType()` 方法设置响应的 MIME 类型,通常设置为 `"text/html"` 表示返回的是 HTML 内容。同时,也可以通过 `setCharacterEncoding()` 方法设置响应的字符编码,确保正确显示特殊字符。 3. 获取输出流:通过 `getWriter()` 方法获取一个 `PrintWriter` 对象,用于向客户端发送内容。 4. 生成 HTML 内容:使用 `PrintWriter` 对象或其他方法,将动态生成的 HTML 内容写入输出流中。 5. 关闭输出流:在生成完整个 HTML 内容后,关闭输出流,确保内容被正确发送到客户端。 6. 服务器发送响应:Servlet 容器将包含动态生成的 HTML 内容的响应发送回客户端浏览器。 7. 浏览器解析和渲染:浏览器接收到响应后,根据响应头中的 MIME 类型和字符编码进行解析和渲染。它会将 HTML 标签解析为页面结构,并加载和执行其中的 CSS 和 JavaScript。 8. 最终呈现页面:浏览器根据解析和执行结果,将最终的页面呈现给用户。 总结来说,Servlet 通过设置响应对象、生成 HTML 内容,并将其发送回浏览器。浏览器接收到响应后,解析和渲染 HTML 内容,最终呈现为可视化的网页。这样实现了在服务器端动态生成 HTML 内容并响应给客户端的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值