什么将是一个更有效的方法来检查错误代码在一个'响应'体比使用' clone() '在一个Cloudflare代理工作者?



目前在Cloudflare worker中做类似的事情

const response = await fetch(...);
const json = await response.clone().json<any>();
if (json.errorCode) {
console.log(json.errorCode, json.message);
return new Response('An error occurred', { status: 500 });
}
return response;

被代理的服务总是返回一个200,所以我必须检查errorCode字段的存在,以知道它是否是一个错误。但是,响应的类型通常是文件或明文,而不是json。clone()似乎是访问响应的最简单的解决方案,同时允许返回它仍然完好无损,但我想知道是否有更好的方法,内存效率更高,可以依赖于流的效率。多年来没有编写节点代码,所以任何帮助都将是感激的!

不幸的是,您在这里基本上无能为力。为了对其进行json解析,您必须读取整个消息(即使您有一个可以处理部分消息的解析器,如果不读取整个消息,您也无法验证字段的缺失)。但是,由于状态码是响应的第一部分,因此在确定状态码之前,无法将数据流传回客户机。因此,您别无选择,只能在内存中缓冲整个响应。

话虽如此,实际上,当您执行.clone()并且只从一个分支读取时,Workers运行时不喜欢它。事实上,在将来,这可能会停止工作,通过减慢所有分支以匹配读取最慢的分支。因此,如果您使用.text().arrayBuffer()将整个主体读入内存,然后使用JSON.parse()将其读入内存,然后使用相同的标头和主体构建新的响应以返回给客户端,则可能会更好。

let text = await response.text();
let json = JSON.parse(text);
if (json.errorCode) {
console.log(json.errorCode, json.message);
return new Response('An error occurred', { status: 500 });
}
return new Response(text, response);

但是很明显这占用了同样多的内存。

也许,作为一个启发式,如果响应大于某个大小,您可以猜测响应不包含错误?因为错误消息可能总是相对较短?尽管实现这种方法的代码会有点复杂,但这至少允许您对需要执行的缓冲量设置一个上限。

最新更新