拦截浏览器对资源的请求

时间:2014-10-22 20:18:08

标签: javascript

是否有任何方法可以加载初始脚本(页面顶部的文件),然后尝试拦截所有其他资源请求(脚本,css,图像等),因为页面继续加载?

此拦截的目的是以缓慢的方式从缓存(localStorage,indexedDB,other)或甚至通过webrtc从远程对等方提供文件,而不依赖于应用程序/页面的组合方式。< / p>

我知道缓存清单/离线方法,但这里的重点是获取所请求的资源并从选择的位置代理它。

2 个答案:

答案 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", …