访问 HTMLRewriter 中的嵌套元素 - Cloudflare Workers
Access nested elements in HTMLRewriter - Cloudflare Workers
我必须在 Cloudflare worker 中使用 HTMLRewriter 访问嵌套元素。
例子
<div data-code="ABC">
<div class="title">Title</div>
<div class="price">9,99</div>
</div>
<div data-code="XYZ">
<div class="title">Title</div>
</div>
我正在考虑使用多个 .on() 但顺序没有保留,因为缺少一些 .price 并且我无法正确合并来自 codeHandler 和 PriceHandler 的结果
await new HTMLRewriter().on("[data-code]", codeHandler)
.on(".price", priceHandler)
.transform(response).arrayBuffer()
我正在考虑多次迭代 new HTMLRewriter() 但可读流被锁定。
当前代码
工人
class codeHandler {
constructor() {
this.values = []
}
element(element) {
let data = {
code: element.getAttribute("data-code"),
title: element.querySelector(".title").innerText, <--
price: element.querySelector(".price").innerText, <--- HERE
}
this.values.push( data )
}
}
const url = "https://www.example.com"
async function handleRequest() {
const response = await fetch(url)
const codeHandler = new codeHandler()
await new HTMLRewriter().on("[data-code]", codeHandler).transform(response).arrayBuffer()
console.log(codeHandler.values)
const json = JSON.stringify(codeHandler.values, null, 2)
return new Response(json, {
headers: {
"content-type": "application/json;charset=UTF-8"
}
})
}
addEventListener("fetch", event => {
return event.respondWith(handleRequest())
})
快速查看文档后,似乎 element
objects in the HTMLRewriter API 当前受到限制,无法按照您希望的方式访问子项。
似乎处理程序 运行 的顺序与文档中出现的顺序相同,这意味着对于您的用例,您可以跟踪当前元素并在该上下文中添加数据.您可以使用闭包使用不同的处理程序来访问相同的数据(在本例中为 values
),如下所示:
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
});
async function handleRequest(request) {
var values = [];
var response = await fetch(request);
function addToLast(attr, text) {
var lastIndex = values.length - 1;
if (lastIndex < 0) {
// this shouldn't happen, since there should always have been
// an object created by the parent [data-code] div
return;
}
// need to add them to the previous value, just in case if there
// are multiple text chunks
values[lastIndex][attr] = (values[lastIndex][attr] || '') + text;
}
await new HTMLRewriter()
.on("[data-code]", {
element(element) {
values.push({
code: element.getAttribute("data-code")
});
},
text(text) {
addToLast('body', text.text);
}
})
.on("[data-code] .title", {
text(text) {
addToLast('title', text.text);
}
})
.on("[data-code] .price", {
text(text) {
addToLast('price', text.text);
}
})
.transform(response).arrayBuffer();
const json = JSON.stringify(values, null, 2)
return new Response(json, {
headers: {
"content-type": "application/json;charset=UTF-8"
}
});
}
另请注意,您可以使用 descendant combinator(例如 [data-code] .title
)来确保处理的唯一 .title
div 是带有 [data-code]
的元素的子元素.
我必须在 Cloudflare worker 中使用 HTMLRewriter 访问嵌套元素。
例子
<div data-code="ABC">
<div class="title">Title</div>
<div class="price">9,99</div>
</div>
<div data-code="XYZ">
<div class="title">Title</div>
</div>
我正在考虑使用多个 .on() 但顺序没有保留,因为缺少一些 .price 并且我无法正确合并来自 codeHandler 和 PriceHandler 的结果
await new HTMLRewriter().on("[data-code]", codeHandler)
.on(".price", priceHandler)
.transform(response).arrayBuffer()
我正在考虑多次迭代 new HTMLRewriter() 但可读流被锁定。
当前代码
工人
class codeHandler {
constructor() {
this.values = []
}
element(element) {
let data = {
code: element.getAttribute("data-code"),
title: element.querySelector(".title").innerText, <--
price: element.querySelector(".price").innerText, <--- HERE
}
this.values.push( data )
}
}
const url = "https://www.example.com"
async function handleRequest() {
const response = await fetch(url)
const codeHandler = new codeHandler()
await new HTMLRewriter().on("[data-code]", codeHandler).transform(response).arrayBuffer()
console.log(codeHandler.values)
const json = JSON.stringify(codeHandler.values, null, 2)
return new Response(json, {
headers: {
"content-type": "application/json;charset=UTF-8"
}
})
}
addEventListener("fetch", event => {
return event.respondWith(handleRequest())
})
快速查看文档后,似乎 element
objects in the HTMLRewriter API 当前受到限制,无法按照您希望的方式访问子项。
似乎处理程序 运行 的顺序与文档中出现的顺序相同,这意味着对于您的用例,您可以跟踪当前元素并在该上下文中添加数据.您可以使用闭包使用不同的处理程序来访问相同的数据(在本例中为 values
),如下所示:
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
});
async function handleRequest(request) {
var values = [];
var response = await fetch(request);
function addToLast(attr, text) {
var lastIndex = values.length - 1;
if (lastIndex < 0) {
// this shouldn't happen, since there should always have been
// an object created by the parent [data-code] div
return;
}
// need to add them to the previous value, just in case if there
// are multiple text chunks
values[lastIndex][attr] = (values[lastIndex][attr] || '') + text;
}
await new HTMLRewriter()
.on("[data-code]", {
element(element) {
values.push({
code: element.getAttribute("data-code")
});
},
text(text) {
addToLast('body', text.text);
}
})
.on("[data-code] .title", {
text(text) {
addToLast('title', text.text);
}
})
.on("[data-code] .price", {
text(text) {
addToLast('price', text.text);
}
})
.transform(response).arrayBuffer();
const json = JSON.stringify(values, null, 2)
return new Response(json, {
headers: {
"content-type": "application/json;charset=UTF-8"
}
});
}
另请注意,您可以使用 descendant combinator(例如 [data-code] .title
)来确保处理的唯一 .title
div 是带有 [data-code]
的元素的子元素.