服务工作者是否可以代理 iframe 子资源?
Is it possible to proxy iframe sub-resources with service workers?
我有一个依赖第 3 方资源的 iframe。 iframe 本身没有 src,不是沙盒,通过 AJAX 填充内容,其子资源(e.x。CSS,图像)存在于 CDN 上不同的域。
在我们或我们的客户发生中断的情况下,我希望能够将 iframe 的 CSS 切换到我们域中的本地文件。我正在尝试通过 Service Worker 中的 fetch 事件来做到这一点:
self.addEventListener('fetch', event => {
const processEpubRequests = () => fetch(`/epubs/${event.request.url.split('epub-resource/')[1]}`);
if(event.request.url.startsWith(`https://our_api.com`))
event.respondWith(
fetch(event.request)
.then(response => response.status >= 400 ? processEpubRequests(response) : response)
.catch(processEpubRequests)
);
else
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
这对于 AJAX 内容请求非常有用,但 CSS 似乎不起作用。它以正确的响应显示在“网络”选项卡中,但 iframe 似乎只是忽略了它。
是否可以这样处理iframe子资源?
谢谢!
编辑:
我制作了一个 Github 页演示来说明我所看到的。
页数:https://soluml.github.io/ServiceWorkerIframeExample/
来源:https://github.com/soluml/ServiceWorkerIframeExample/tree/gh-pages
原来有一个Chrome bug out there for this issue. There are also several related issues for Firefox。
但是,我们可以通过以下方式解决此问题:
- 将 iframe 标记设置为同源虚拟 src。
<iframe src=".iframe"></iframe>
- 在我们的 service worker 中响应虚拟 src(如果我们使用一个而不是实际的空白 html 文件)
if(event.request.url == `${self.location.origin}/.iframe`)
event.respondWith(
new Response(`<!doctype html><title>i</title>`, {
status: 200,
headers: { "Content-Type": "text/html" }
})
);
- 不使用
contentDocument.write()
,而是使用 doc.documentElement.innerHTML
。这将不会更改 iframe 中现有的 <html>
标记和 DOCTYPE。
我有一个依赖第 3 方资源的 iframe。 iframe 本身没有 src,不是沙盒,通过 AJAX 填充内容,其子资源(e.x。CSS,图像)存在于 CDN 上不同的域。
在我们或我们的客户发生中断的情况下,我希望能够将 iframe 的 CSS 切换到我们域中的本地文件。我正在尝试通过 Service Worker 中的 fetch 事件来做到这一点:
self.addEventListener('fetch', event => {
const processEpubRequests = () => fetch(`/epubs/${event.request.url.split('epub-resource/')[1]}`);
if(event.request.url.startsWith(`https://our_api.com`))
event.respondWith(
fetch(event.request)
.then(response => response.status >= 400 ? processEpubRequests(response) : response)
.catch(processEpubRequests)
);
else
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
这对于 AJAX 内容请求非常有用,但 CSS 似乎不起作用。它以正确的响应显示在“网络”选项卡中,但 iframe 似乎只是忽略了它。
是否可以这样处理iframe子资源?
谢谢!
编辑: 我制作了一个 Github 页演示来说明我所看到的。 页数:https://soluml.github.io/ServiceWorkerIframeExample/ 来源:https://github.com/soluml/ServiceWorkerIframeExample/tree/gh-pages
原来有一个Chrome bug out there for this issue. There are also several related issues for Firefox。
但是,我们可以通过以下方式解决此问题:
- 将 iframe 标记设置为同源虚拟 src。
<iframe src=".iframe"></iframe>
- 在我们的 service worker 中响应虚拟 src(如果我们使用一个而不是实际的空白 html 文件)
if(event.request.url == `${self.location.origin}/.iframe`)
event.respondWith(
new Response(`<!doctype html><title>i</title>`, {
status: 200,
headers: { "Content-Type": "text/html" }
})
);
- 不使用
contentDocument.write()
,而是使用doc.documentElement.innerHTML
。这将不会更改 iframe 中现有的<html>
标记和 DOCTYPE。