合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
# HTML重写器 * [总览](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#overview) * [HTML重写器](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#htmlrewriter) * [选择器](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#selectors) * [全局类型](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#global-types) * [处理程序](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#handlers) * [元素处理程序](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#element-handlers) * [文件处理员](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#document-handlers) * [元件](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#element) * [文字块](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#text-chunks) * [评论](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#comments) * [文件类型](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#doctype) * [了解处理程序错误](https://developers.cloudflare.com/workers/reference/apis/html-rewriter/#understanding-handler-errors) ## 总览 本`HTMLRewriter`类允许开发者建立全面和表现HTML解析器一个CloudFlare的工人应用程序内部。可以将其视为直接在Workers应用程序内部的类似于jQuery的体验。依靠强大的JavaScript API来解析和转换HTML,`HTMLRewriter`允许开发人员构建功能强大的应用程序。 ## HTML重写器 本`HTMLRewriter`类应该曾经在你的工人脚本被实例化,使用附加了一些处理程序`on`和`onDocument`功能: ~~~js new HTMLRewriter.on('*', new ElementHandler()).onDocument(new DocumentHandler()) ~~~ ## 选择器 | 图案 | 代表 | | --- | --- | | `*` | 任何元素 | | `E` | 任何类型E的元素 | | `E:not(s)` | 与两个复合选择器都不匹配的E元素 | | `E.warning` | 属于类警告的E元素 | | `E#myid` | ID等于myid的E元素。 | | `E[foo]` | 具有foo属性的E元素 | | `E[foo="bar"]` | 一个E元素,其foo属性值完全等于bar | | `E[foo="bar" i]` | 一个E元素,其foo属性值完全等于bar的任何(ASCII范围)大小写排列 | | `E[foo="bar" s]` | 一个E元素,其foo属性值与大小写精确且等于bar | | `E[foo~="bar"]` | 一个E元素,其foo属性值是由空格分隔的值的列表,其中一个值等于bar | | `E[foo^="bar"]` | 一个E元素,其foo属性值完全以字符串bar开头 | | `E[foo$="bar"]` | 一个E元素,其foo属性值恰好以字符串bar结尾 | | `E[foo*="bar"]` | 一个E元素,其foo属性值包含子字符串栏 | | `E[foo|="en"]` | 一个E元素,其foo属性值是一个用连字符分隔的值列表,以en开头 | | `E F` | E元素的F元素后代 | | `E > F` | E元素的F元素子元素 | ## 全局类型 在整个HTMLRewriter API中,许多属性和方法使用一些一致的类型: * `Content`:`String`。插入输出流中的内容应为字符串。 * `ContentOptions`:`{ html: Boolean }`。控制HTMLRewriter处理插入内容的方式。如果`html`布尔值设置为true,则将内容视为原始HTML。如果`html`布尔值设置为false或未提供,则将内容视为文本,并将对其应用适当的HTML转义。 ## 处理程序 可以使用两种处理程序类型`HTMLRewriter`:*元素处理程序*和*文档处理程序*。 ### 元素处理程序 使用实例`.on`函数附加元素处理程序时,它会响应任何传入的元素`HTMLRewriter`。元素处理应该做出响应`element`,`comments`以及`text`。以下示例将`div`使用`ElementHandler`类处理元素: ~~~js class ElementHandler { element(element) { // An incoming element, such as `div` console.log(`Incoming element: ${element.tagName}`) } comments(comment) { // An incoming comment } text(text) { // An incoming piece of text } } async function handleRequest(req) { const res = await fetch(req) return new HTMLRewriter().on('div', new ElementHandler()).transform(res) } ~~~ ### 文件处理员 文档处理程序代表传入的HTML文档。许多功能都可以在文档处理程序被定义为查询和操作文档的`doctype`,`comments`和`text`。不像元素管理器,文档处理程序的`doctype`,`comments`并且`text`功能不被特定的选择范围的,并呼吁包括的内容网页上的所有内容*之外*的顶级HTML标签: ~~~js class DocumentHandler { doctype(doctype) { // An incoming doctype, such as <!DOCTYPE html> } comments(comment) { // An incoming comment } text(text) { // An incoming piece of text } } ~~~ ### 元件 `element`仅在元素处理程序中使用的参数是DOM元素的表示形式。元素上存在许多方法来查询和操作它: #### Properties 属性 * `tagName`:`String`代表标签名称,例如`"h1"`或`"div"`。可以为该属性分配不同的值,以修改元素的标签。 * `attributes`:`Iterator`返回一`[name, value]`对标记属性。该属性是只读的。 * `removed`:`Boolean`指示元素是否已被先前的处理程序之一删除或替换。 * `namespaceURI`:`String`表示元素的[名称空间URI](https://infra.spec.whatwg.org/#namespaces)。 #### 方法 * `getAttribute(name: String): String | null`:返回元素上给定属性名称的值,`null`如果找不到,则返回该值。 * `hasAttribute(name: String): Boolean`:返回一个布尔值,指示元素上是否存在属性。 * `setAttribute(name: String, value: String): Element`:将属性设置为提供的值,如果不存在则创建该属性。 * `removeAttribute(name: String): Element`:删除属性。 * `before(content: Content, contentOptions?: ContentOptions): Element`:在元素之前插入内容。 * `after(content: Content, contentOptions?: ContentOptions): Element`:在元素之后插入内容。 * `prepend(content: Content, contentOptions?: ContentOptions): Element`:在元素的开始标记之后插入内容。 * `append(content: Content, contentOptions?: ContentOptions): Element`:在元素的结束标记之前插入内容。 * `replace(content: Content, contentOptions?: ContentOptions): Element`:删除元素并在其中插入内容。 * `setInnerContent(content: Content, contentOptions?: ContentOptions): Element`:替换元素的内容。 * `remove(): Element`:删除元素及其所有内容。 * `removeAndKeepContent(): Element`:删除元素的开始标签和结束标签,但保持其内部内容不变。 ### 文字块 由于我们执行零拷贝流解析,因此文本块与词法树中的文本节点不同。一个词法树的文本节点可以由多个块表示,因为它们从原点通过电线到达。 考虑以下标记:`<div>Hey. How are you?</div>`。Workers脚本有可能不会一次从原点接收整个文本节点。相反,`text`将为文本节点的每个接收到的部分调用元素处理程序。例如,可以使用“嘿,怎么样”,然后“你是?”来调用处理程序。当最后一块到达时,文本的`lastInTextNode`属性将设置为`true`。开发人员应确保将这些块连接在一起。 #### Properties 属性 * `removed`:`Boolean`指示元素是否已被先前的处理程序之一删除或替换。 * `text: String`:块的只读文本内容。如果该块是文本节点的最后一个块,则可以为空。 * `lastInTextNode`::`Boolean`只读,指定该块是否为文本节点的最后一个块。 #### 方法 * `before(content: Content, contentOptions?: ContentOptions): Element`:在元素之前插入内容。 * `after(content: Content, contentOptions?: ContentOptions): Element`:在元素之后插入内容。 * `replace(content: Content, contentOptions?: ContentOptions): Element`:删除元素并在其中插入内容。 * `remove(): Element`:删除元素及其所有内容。 ### 评论 在`comments`上一个元素处理函数允许开发人员查询和操作HTML注释标记。 ~~~js class ElementHandler { comments(comment) { // An incoming comment element, such as <!-- My comment --> } } ~~~ #### Properties 属性 * `removed`:`Boolean`指示元素是否已被先前的处理程序之一删除或替换。 * `text`:`String`代表评论文字。可以为该属性分配不同的值,以修改评论的文本。 #### 方法 * `before(content: Content, contentOptions?: ContentOptions): Element`:在元素之前插入内容。 * `after(content: Content, contentOptions?: ContentOptions): Element`:在元素之后插入内容。 * `replace(content: Content, contentOptions?: ContentOptions): Element`:删除元素并在其中插入内容。 * `remove(): Element`:删除元素及其所有内容。 ### 文件类型 在`doctype`一个文档处理程序功能允许开发人员查询文档的[文档类型](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)。 ~~~js class DocumentHandler { doctype(doctype) { // An incoming doctype element, such as // <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> } } ~~~ #### Properties 属性 * `name: String | null`:只读,表示文档类型名称的字符串。 * `publicId: String | null`:只读,PUBLIC原子后的doctype中带引号的字符串。 * `systemId: String | null`:只读,doctype中带引号的字符串在SYSTEM原子之后或紧随在`publicId`。 ## 了解处理程序错误 如果处理程序引发异常,则将立即停止解析,转换的响应主体会因引发的异常而出错,并且未转换的响应主体将被取消(关闭)。如果已将转换后的响应主体部分流回客户端,则客户端将看到截断的响应。 ~~~js async function handle(request) { let oldResponse = await fetch(request) let newResponse = new HTMLRewriter() .on('*', { element(element) { throw new Error('A really bad error.') }, }) .transform(oldResponse) // At this point, an expression like `await newResponse.text()` // will throw `new Error("A really bad error.")`. // Thereafter, any use of `newResponse.body` will throw the same error, // and `oldResponse.body` will be closed. // Alternatively, this will produce a truncated response to the client: return newResponse } ~~~