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

Lan*_*ard 11 javascript networking google-chrome-extension node.js

有没有办法访问浏览器请求的资源列表(在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"}`
}
Run Code Online (Sandbox Code Playgroud)

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

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

它不需要跨浏览器工作,甚至可以使用客户端JavaScript.能够以任何方式访问此信息都可行(可能有一些方法可以使用phantomjs或观察来自shell/node脚本的网络流量).有任何想法吗?

Ell*_* B. 9

您可以执行此操作,但您需要使用Chrome扩展程序.

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

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

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

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

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

content_script.js

document.getElementById("theButton").addEventListener("click", function() {
    window.postMessage({ type: "TO_PAGE", text: "Hello from the extension!" }, "*");
}, false);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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

`5.使用消息传递将Web请求的信息转发到内容脚本,然后转发到网页JavaScript.

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

Chrome扩展程序和内容脚本

完整的工作示例:

前三个文件包含您的Google Chrome扩展程序,最后一个文件是您应该上传到http://网络空间的HTML文件.

的icon.png

使用任何16x16 PNG文件.

的manifest.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
}
Run Code Online (Sandbox Code Playgroud)

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);
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

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);
});
Run Code Online (Sandbox Code Playgroud)

并将以下内容用于网页(以您想要的名称命名):

<!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>
Run Code Online (Sandbox Code Playgroud)