# 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
}
~~~
- 关于本翻译文档
- 快速开始
- 模版库
- 讲解
- Workers页面
- 从0开始
- 从已有页面开始
- 从已有Worder开始
- 工具
- Cli工具 wrangler
- 安装
- 指令
- 配置
- 环境
- Webpack
- 密钥
- KV
- 网站
- Playground
- ServerLess插件
- Terraform
- REST API
- Making Requests
- Scripts
- Bindings
- Routes
- Integrations
- 相关
- 工作原理
- 安全
- 使用缓存
- 价格
- Routes
- Limits
- 提示
- 调试技巧
- 调试header
- FetchEvent生命周期
- 请求上下文
- 请求sign
- 参考
- runtime API
- Web Standards
- fetch
- fetchEvent
- Response
- Request
- KV
- Environment Variables
- Streams
- Encoding
- Web Crypto
- Cache API
- HTMLRewriter
- Workers KV
- Use cases
- Namespaces