是否有任何方法可以加载初始脚本(页面顶部的文件),然后尝试拦截所有其他资源请求(脚本,css,图像等),因为页面继续加载?
此拦截的目的是以缓慢的方式从缓存(localStorage,indexedDB,other)或甚至通过webrtc从远程对等方提供文件,而不依赖于应用程序/页面的组合方式。< / p>
我知道缓存清单/离线方法,但这里的重点是获取所请求的资源并从选择的位置代理它。
答案 0 :(得分:1)
一种解决方案是在第一个脚本中注册服务工作者以拦截请求。
唯一的问题是,该注册是异步的,而资源是同步加载的,这意味着在第一次加载时将获取原始资源。
不过,一旦加载服务工作者,简单的页面刷新就可以加载被拦截的资源。
下面的代码检测服务工作程序是否是首次加载(或在Ctrl+F5
之后),如果是,则在注册回调中执行页面刷新。这是解决上述问题的一种方法,可能不是最优雅的方法。
在下面的示例中,image / js资源是从外部url加载的,但是可以是任何来源。 script.js
可以添加到所有页面的顶部。
https://next.plnkr.co/edit/dP6wr0hB1gbXDeQs?preview
html
<html>
<body>
<h2>My intercepted page</h2>
<script src="script.js"></script>
<script src="jquery.js"></script>
<div class="placeholder">a</div>
<img src="z9t29Bk.gif">
<img src="y2kChjZ.gif">
<script>$(".placeholder").text("loaded jquery version:"+$.fn.jquery)</script>
</body>
</html>
script.js
if ('serviceWorker' in navigator) {
var interceptorLoaded = navigator.serviceWorker.controller!=null;
window.addEventListener('load', function() {
navigator.serviceWorker.register('sw.js')
.then(function(registration){
console.log('ServiceWorker registration successful with scope: ', registration.scope);
if(!interceptorLoaded){
//refresh after interceptor was loaded but only if the interceptor was not already loaded.
window.location=window.location.href;
}
},
function(err) { // registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
});
}
sw.js
self.addEventListener('fetch', function(event) {
console.log("REQUEST:", event.request.url);
var url = event.request.url;
if (url.endsWith("/jquery.js")) {
event.respondWith(
fetch('https://code.jquery.com/jquery-3.3.1.js')
);
}else if(url.endsWith(".jpg") || url.endsWith(".png") || url.endsWith(".gif")){
event.respondWith(fetch("https://i.imgur.com/"+url.substring(url.lastIndexOf("/")+1),{
mode: 'cors',
}));
}
})
参考:https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer
答案 1 :(得分:0)
也许可以使用PerformanceObserver。
const observer2 = new PerformanceObserver((entries) => {
entries.getEntriesByType("resource").forEach(res => console.log(res.toJSON()))
});
observer2.observe({ entryTypes: ["resource"] });
// {name: "http://localhost:8080/1.1.0/img/my_arrow_top.9283728e.svg", entryType: "resource", startTime: 3266.3399999946705, duration: 26.8900000010035, initiatorType: "img", …}
// {name: "http://localhost:8080/1.1.0/img/my_icon.f210d94a.svg", entryType: "resource", startTime: 3266.9349999996484, duration: 44.04000000067754, initiatorType: "img", …}
// {name: "http://localhost:8080/1.1.0/img/my_list_bill.90ea3a37.svg", entryType: "resource", startTime: 3267.26499999495, duration: 46.875, initiatorType: "img", …}
// {name: "http://localhost:8080/1.1.0/img/list_arrow.46347d10.svg", entryType: "resource", startTime: 3268.0749999999534, duration: 49.924999999348074, initiatorType: "img", …}
// {name: "http://localhost:8080/1.1.0/img/my_list_card.fa9a853c.svg", entryType: "resource", startTime: 3269.0549999970244, duration: 53.15500000142492, initiatorType: "img", …}
// {name: "http://localhost:8080/1.1.0/img/my_list_invite.89c26861.svg", entryType: "resource", startTime: 3270.7399999999325, duration: 56.94499999663094, initiatorType: "img", …}
// {name: "http://localhost:8080/1.1.0/img/my_list_loan.ebbd740a.svg", entryType: "resource", startTime: 3271.2849999952596, duration: 60.380000002624, initiatorType: "img", …}
// {name: "http://localhost:8080/1.1.0/img/my_list_about.cacfe7f5.svg", entryType: "resource", startTime: 3271.7199999970035, duration: 61.67000000277767, initiatorType: "img", …