如何在 JavaScript 中记录获取的网络资源?

Posted

技术标签:

【中文标题】如何在 JavaScript 中记录获取的网络资源?【英文标题】:How to log fetched network resources in JavaScript? 【发布时间】:2013-01-04 01:03:42 【问题描述】:

有没有办法访问浏览器请求的资源列表(在这个 Chrome 检查器的网络面板中找到的资源)?

我希望能够遍历这些获取的资源以显示已访问的域,例如:

for (var i = 0; i < window.navigator.resources.length; i++) 
  var resource = window.navigator.resources[i];
  console.log(resource); //=> e.g. `domain: "www.google-analytics.com", name: "ga.js"`

或者,也许有一些事件要为其编写处理程序,例如:

window.navigator.onrequest = function(resource) 
  console.log(resource); //=> e.g. `domain: "www.google-analytics.com", name: "ga.js"`

它不需要跨浏览器工作,甚至可以使用客户端 javascript。只要能够以任何方式 访问这些信息就可以了(也许有某种方法可以使用 phantomjs 或从 shell/node 脚本监视网络流量)。有什么想法吗?

【问题讨论】:

【参考方案1】:

您可以这样做,但您需要使用 Chrome 扩展程序。

Chrome 扩展程序具有很多沙盒式的安全性。 Chrome 扩展程序和网页之间的通信是一个多步骤的过程。这是我能提供的最简洁的解释,最后附有一个完整的工作示例:

    Chrome 扩展程序可以完全访问 chrome.* API,但 Chrome 扩展程序不能直接与网页 JS 通信,网页 JS 也不能直接与 Chrome 扩展程序通信.

    要弥合 Chrome 扩展程序和网页之间的差距,您需要使用 content script 。内容脚本本质上是在目标网页的window 范围内注入的 JavaScript。内容脚本不能调用函数,也不能访问由网页 JS 创建的变量,但它们确实共享对同一个 DOM 的访问权,因此也共享事件。

    因为不允许直接访问变量和调用函数,所以网页和内容脚本通信的唯一方式是通过触发自定义事件

例如,如果我想将消息从 Chrome 扩展程序传递到页面,我可以这样做:

content_script.js

document.getElementById("theButton").addEventListener("click", function() 
    window.postMessage( type: "TO_PAGE", text: "Hello from the extension!" , "*");
, false);

web_page.js

window.addEventListener("message", function(event) 
    // We only accept messages from ourselves
    if (event.source != window)
      return;

    if (event.data.type && (event.data.type == "TO_PAGE")) 
      alert("Received from the content script: " + event.data.text);
    
, false);

`4.现在您可以从内容脚本向网页发送消息,您现在需要 Chrome 扩展程序收集您想要的所有网络信息。您可以通过几个不同的模块来完成此操作,但最简单的选项是 webRequest 模块(请参阅下面的 background.js)。

`5.使用message passing 将网络请求的信息传递到内容脚本,然后传递到网页 JavaScript。

在视觉上,你可以这样想:

完整的工作示例:

前三个文件构成您的 Google Chrome 扩展程序,最后一个文件是您应该上传到某处 http:// 网络空间的 html 文件。

icon.png

使用任何 16x16 PNG 文件。

ma​​nifest.json


  "name": "webRequest Logging",
  "description": "Displays the network log on the web page",
  "version": "0.1",
  "permissions": [
    "tabs",
    "debugger",
    "webRequest",
    "http://*/*"
  ],
  "background": 
    "scripts": ["background.js"]
  ,
  "browser_action": 
    "default_icon": "icon.png",
    "default_title": "webRequest Logging"
  ,
   "content_scripts": [
    
      "matches": ["http://*/*"],
      "js": ["content_script.js"]
    
  ],
  "manifest_version": 2

background.js

var aNetworkLog = [];

chrome.webRequest.onCompleted.addListener(function(oCompleted) 
            var sCompleted = JSON.stringify(oCompleted);
            aNetworkLog.push(sCompleted);
        
        ,urls: ["http://*/*"]
 );

chrome.extension.onConnect.addListener(function (port) 
    port.onMessage.addListener(function (message) 
        if (message.action == "getNetworkLog") 
            port.postMessage(aNetworkLog);
        
    );
);

content_script.js

var port = chrome.extension.connect(name:'test');

document.getElementById("theButton").addEventListener("click", function() 

    port.postMessage(action:"getNetworkLog");

, false);

port.onMessage.addListener(function(msg) 
  document.getElementById('outputDiv').innerHTML = JSON.stringify(msg);
);

并为网页使用以下内容(随便命名):

<!doctype html>
<html>
<head>
    <title>webRequest Log</title>
</head>
<body>
    <input type="button" value="Retrieve webRequest Log" id="theButton">
    <div id="outputDiv"></div>
</head>
</html>

【讨论】:

大多数人使用debugger API,这是一些新的 +1 :)【参考方案2】:

向@Elliot B 致敬。

我基本上使用了他所做的,但我希望在内容脚本中触发事件,而不是在后台触发侦听器。无论出于何种原因,我无法从后台脚本连接到端口,所以这就是我想出的。

PS:你需要扩展文件夹中的 jquery.js 来完成这项工作。

manifest.json


  "manifest_version": 2,

  "name": "MNC",
  "version": "0.0.1",
  "description": "Monitor Network Comms",
  "permissions":["webRequest","*://*/"],
  "content_scripts": [
  "matches": ["<all_urls>"],
  "run_at": "document_start",
  "js": ["content.js",
        "jquery.js"]
  ],
  "background": 
    "scripts": ["background.js"]
  

background.js

var aNetworkLog = [];

chrome.webRequest.onResponseStarted.addListener(
  function(oCompleted) 
    var sCompleted = JSON.stringify(oCompleted);
    aNetworkLog.push(sCompleted);
  ,urls: ["https://*/*"]
);

chrome.extension.onConnect.addListener(function (port) 
  chrome.webRequest.onResponseStarted.addListener(
    function()
      port.postMessage(networkLog:JSON.stringify(aNetworkLog));
    ,urls: ["https://*/*"]
  );
  port.onMessage.addListener(function (message) 
    if (message.disconnect==true) 
      port.disconnect();
    
  );
);

content.js

div = $('<div id="outputDiv" style="float:left;max-width:fit-content;position:fixed;display:none;"></div>').appendTo(document.body);
var port = chrome.extension.connect(name:'networkLogging');
port.onMessage.addListener(function (message) 
  if (message.networkLog) 
    div[0].innerHTML = message.networkLog;
  
);
observer = new WebKitMutationObserver(function(mutation,observer)
  JSON.parse(mutation[0]['target'].innerHTML).forEach(function(item)
    JSON.parse(item);
  )
);
observer.observe(div[0],childList:true);

这绝对不是最有效的做事方式,但它对我有用。以为我会在这里添加它以防万一有人需要它。

【讨论】:

以上是关于如何在 JavaScript 中记录获取的网络资源?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 JavaScript 获取 html 表格 td 单元格值?

如何使用javascript在特定播放点获取mp3的音量

如何使用 Youtube Javascript API 获取 youtube 用户的观看历史记录?

如何使用 JavaScript 获取本地/内部 IP

如何从 jquery 或 javascript 中的两个不同数组中查找唯一记录?

如何获取由 HTML 完成的网络请求列表