event.passThroughOnException 向源发送请求,但没有 POST 数据
event.passThroughOnException sends requests to origin, but without POST data
我认为 event.passThroughOnException();
应该为我的工作人员设置 fail open
策略,这样如果我的代码出现异常,原始请求就会发送到我的源服务器,但似乎它缺少 post 数据。我认为这是因为请求体是一个可读流,一旦读取就无法再次读取,但是如何管理这种情况?
addEventListener('fetch', (event) => {
event.passThroughOnException();
event.respondWith(handleRequest(event));
});
async function handleRequest(event: FetchEvent): Promise<Response> {
const response = await fetch(event.request);
// do something here that potentially raises an Exception
// @ts-ignore
ohnoez(); // deliberate failure
return response;
}
如下图所示,源服务器没有收到任何正文(foobar
):
不幸的是,这是 passThroughOnException()
的已知限制。 Workers Runtime 对请求和响应主体使用流;它不会缓冲 body。结果,body 一旦被消耗,它就没有了。所以如果你转发请求,然后抛出异常,请求body就不能再发送了。
通过克隆 event.request
来解决问题,然后在 handleRequest
中添加 try/catch。在 catch(err)
上,使用 fetch
将请求发送到源,同时传递克隆的请求。
// Pass request to whatever it requested
async function passThrough(request: Request): Promise<Response> {
try {
let response = await fetch(request)
// Make the headers mutable by re-constructing the Response.
response = new Response(response.body, response)
return response
} catch (err) {
return ErrorResponse.NewError(err).respond()
}
}
// request handler
async function handleRequest(event: FetchEvent): Promise<Response> {
const request = event.request
const requestClone = event.request.clone()
let resp
try {
// handle request
resp = await handler.api(request)
} catch (err) {
// Pass through manually on exception (because event.passThroughOnException
// does not pass request body, so use that as a last resort)
resp = await passThrough(requestClone)
}
return resp
}
addEventListener('fetch', (event) => {
// Still added passThroughOnException here
// in case the `passThrough` function throws exception
event.passThroughOnException()
event.respondWith(handleRequest(event))
})
到目前为止似乎工作正常。很想知道是否还有其他解决方案。
我认为 event.passThroughOnException();
应该为我的工作人员设置 fail open
策略,这样如果我的代码出现异常,原始请求就会发送到我的源服务器,但似乎它缺少 post 数据。我认为这是因为请求体是一个可读流,一旦读取就无法再次读取,但是如何管理这种情况?
addEventListener('fetch', (event) => {
event.passThroughOnException();
event.respondWith(handleRequest(event));
});
async function handleRequest(event: FetchEvent): Promise<Response> {
const response = await fetch(event.request);
// do something here that potentially raises an Exception
// @ts-ignore
ohnoez(); // deliberate failure
return response;
}
如下图所示,源服务器没有收到任何正文(foobar
):
不幸的是,这是 passThroughOnException()
的已知限制。 Workers Runtime 对请求和响应主体使用流;它不会缓冲 body。结果,body 一旦被消耗,它就没有了。所以如果你转发请求,然后抛出异常,请求body就不能再发送了。
通过克隆 event.request
来解决问题,然后在 handleRequest
中添加 try/catch。在 catch(err)
上,使用 fetch
将请求发送到源,同时传递克隆的请求。
// Pass request to whatever it requested
async function passThrough(request: Request): Promise<Response> {
try {
let response = await fetch(request)
// Make the headers mutable by re-constructing the Response.
response = new Response(response.body, response)
return response
} catch (err) {
return ErrorResponse.NewError(err).respond()
}
}
// request handler
async function handleRequest(event: FetchEvent): Promise<Response> {
const request = event.request
const requestClone = event.request.clone()
let resp
try {
// handle request
resp = await handler.api(request)
} catch (err) {
// Pass through manually on exception (because event.passThroughOnException
// does not pass request body, so use that as a last resort)
resp = await passThrough(requestClone)
}
return resp
}
addEventListener('fetch', (event) => {
// Still added passThroughOnException here
// in case the `passThrough` function throws exception
event.passThroughOnException()
event.respondWith(handleRequest(event))
})
到目前为止似乎工作正常。很想知道是否还有其他解决方案。