![](/img/trans.png)
[英]Access nested elements in HTMLRewriter - Cloudflare Workers
[英]Set response headers from HTMLRewriter in Cloudflare Workers
我正在使用HTMLRewriter查找要预加载的图像。 有没有办法使用服务人员将它们作为“链接”响应 header 注入?
addEventListener('fetch', (event) => {
event.passThroughOnException()
event.respondWith(handleRequest(event.request))
})
class ElementHandler {
element(element) {
console.log(`Incoming image: ${element.getAttribute('src')}`)
// Add this image to response header (as link)
}
}
async function handleRequest(req) {
const res = await fetch(req)
return new HTMLRewriter().on('img[loading=eager]', new ElementHandler()).transform(res)
}
这里有一个基本问题: HTMLRewriter
旨在在 HTML 流过时重写它,因此您不必一次将整个文档加载到 memory 中。 但是,如果内容正在流式传输,则意味着响应标头必须已经发送到客户端,因为 HTTP 直到响应标头之后才允许流式传输内容。 (从技术上讲,HTTP 支持称为“拖车”的东西,但在这里它们无济于事。)
为了根据使用HTMLRewriter
解析的数据填充标头,您必须将整个 HTML 缓冲到 memory 中。 这通常是不可取的:
<img>
标签就可以开始加载每个图像。 只有在能够比 HTML 内容更早交付的情况下,预加载标头才会有所帮助。 但是,如果您的工作人员无论如何都必须读取 HTML 内容才能找到这些标签,并且同时延迟向客户端交付内容,则延迟可能会总体上更糟。综上所述,将内容读入 memory 的代码如下所示:
class ElementHandler {
constructor() {
this.links = [];
}
element(element) {
// Remember the link off to the side.
this.links.push(element.getAttribute('src'));
}
addHeadersTo(res) {
// ... add this.links to res.headers here ...
}
}
async function handleRequest(req) {
const res = await fetch(req);
let handler = new ElementHandler();
let res2 = new HTMLRewriter()
.on('img[loading=eager]', handler).transform(res);
// Force entire HTML to be read into memory.
// THIS IS INEFFICIENT!
let data = await res2.arrayBuffer();
// Make a THIRD response based on the buffered data
// that we consumed from res2.
let res3 = new Response(data, res2);
// Modify its headers based on the links.
handler.addHeadersTo(res3);
// Now we can return that.
return res3;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.