Service Worker:拦截响应
Service worker: intercept responses
我知道我可以使用 service worker 来拦截传出的 fetch
操作,甚至可以为它们生成自定义响应,例如
self.addEventListener('fetch', (event) => {
if (/\.jpg$/.test(event.request.url)) {
event.respondWith(
fetch('/images/anotherimage.jpg'));
}
});
但是,如果我想在给定 fetch
请求的响应传回页面之前拦截该响应怎么办?这可行吗?
明确地说,我不想以任何方式修改请求本身 - 我只想访问对它的响应。
我假设你的意思是你想向服务工作人员添加逻辑,以便它请求资源,然后修改来自网络的响应,从而产生一个返回到页面的响应是您从网络获得的内容和服务工作者添加的内容的混合。
如果是这样,答案是肯定的,您可以对同源响应执行此操作,并在使用 CORS 时对跨源响应执行此操作。 (您不能修改 opaque responses,这是在不使用 CORS 的情况下发出跨源请求时得到的结果。)
这是一个 fetch
处理程序的示例,它响应对假设 /api
端点的请求,returns JSON 我向 /api
发出请求,然后在将响应返回到页面之前向 API 响应添加一个附加字段。
async function modifyAPIResponse(request) {
const apiResponse = await fetch(request);
const json = await apiResponse.json();
json.extraField = 'set by fetch handler';
return new Response(JSON.stringify(json), {
// Ensure that the Content-Type: and other headers are set.
headers: apiResponse.headers,
});
}
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (url.pathname === '/api') {
event.respondWith(modifyAPIResponse(event.request));
}
});
我知道我可以使用 service worker 来拦截传出的 fetch
操作,甚至可以为它们生成自定义响应,例如
self.addEventListener('fetch', (event) => {
if (/\.jpg$/.test(event.request.url)) {
event.respondWith(
fetch('/images/anotherimage.jpg'));
}
});
但是,如果我想在给定 fetch
请求的响应传回页面之前拦截该响应怎么办?这可行吗?
明确地说,我不想以任何方式修改请求本身 - 我只想访问对它的响应。
我假设你的意思是你想向服务工作人员添加逻辑,以便它请求资源,然后修改来自网络的响应,从而产生一个返回到页面的响应是您从网络获得的内容和服务工作者添加的内容的混合。
如果是这样,答案是肯定的,您可以对同源响应执行此操作,并在使用 CORS 时对跨源响应执行此操作。 (您不能修改 opaque responses,这是在不使用 CORS 的情况下发出跨源请求时得到的结果。)
这是一个 fetch
处理程序的示例,它响应对假设 /api
端点的请求,returns JSON 我向 /api
发出请求,然后在将响应返回到页面之前向 API 响应添加一个附加字段。
async function modifyAPIResponse(request) {
const apiResponse = await fetch(request);
const json = await apiResponse.json();
json.extraField = 'set by fetch handler';
return new Response(JSON.stringify(json), {
// Ensure that the Content-Type: and other headers are set.
headers: apiResponse.headers,
});
}
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (url.pathname === '/api') {
event.respondWith(modifyAPIResponse(event.request));
}
});