如何在Cloudflare Worker中提前终止HTMLRewriter并正常返回JSON响应
HTMLRewriter 提前终止的非错误实现方案
核心思路
利用TransformStream做流的中间拦截,在收集到所有目标内容后直接丢弃后续的流块,无需抛出错误即可终止HTMLRewriter的后续解析,不会触发平台故障日志。
实现代码
export default { async fetch(request) { // 存储解析结果 const targetItems = [] // 完成标记:收集到所有目标后置为true let parseCompleted = false // 按需配置需要收集的目标数量,单个目标的话设为1即可 const REQUIRED_ITEM_COUNT = 3 // 请求上游HTML页面 const upstreamResponse = await fetch("https://你的目标页面地址", request) // 自定义可控转换流,控制是否向下游传输数据 const controllableTransform = new TransformStream({ transform(chunk, controller) { // 已完成解析的话直接丢弃后续数据块 if (parseCompleted) return controller.enqueue(chunk) } }) // 初始化HTMLRewriter,配置你的解析规则 const rewriter = new HTMLRewriter() // 示例:匹配class为item的元素,提取href属性 .on(".item a", { element(element) { const itemUrl = element.getAttribute("href") targetItems.push(itemUrl) // 达到目标数量后标记解析完成 if (targetItems.length >= REQUIRED_ITEM_COUNT) { parseCompleted = true } } }) // 示例2:匹配class为title的元素,提取文本内容 .on(".title", { text(textChunk) { if (textChunk.lastInTextNode) { targetItems.push(textChunk.text.trim()) if (targetItems.length >= REQUIRED_ITEM_COUNT) { parseCompleted = true } } } }) // 启动流处理,不需要等待全部解析完成 rewriter.transform( new Response(upstreamResponse.body.pipeThrough(controllableTransform)) ) // 等待解析完成 while (!parseCompleted) { await new Promise(resolve => setTimeout(resolve, 1)) } // 直接返回JSON响应 return Response.json({ code: 0, data: targetItems }) } }
注意事项
- 你可以根据实际业务调整完成条件,比如找到某一个指定ID的元素就标记
parseCompleted = true,不需要固定收集数量。 - 该方案不会产生额外的资源损耗,当你返回JSON响应后,Cloudflare Worker运行环境会自动清理未处理完的上游连接,不会继续拉取剩余的HTML内容。
- 全程无错误抛出,不会被平台日志记录为故障事件。
内容的提问来源于stack exchange,提问作者Kip Olson
相关产品推荐
相关产品推荐

