繁体   English   中英

在 Cloudflare Workers 中从 HTMLRewriter 设置响应标头

[英]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 中。 这通常是不可取的:

  • 这将使您的 Worker 更有可能达到 memory 限制并失败。
  • 这意味着您需要先从源获取整个响应,然后才能将其发送到客户端,这会增加延迟。 这实际上可能会破坏预加载优化的目的。 当 HTML 流到浏览器时,浏览器一看到<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM