Как регистрировать загруженные сетевые ресурсы в JavaScript?

Есть ли способ получить доступ к списку ресурсов, которые запрашивал браузер (те, которые были найдены на этой панели панели инспектора Chrome)?

Network Resources

Я хотел бы иметь возможность выполнять итерацию через эти извлеченные ресурсы, чтобы показать доступ к доменам, например:

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 или просмотра сетевого трафика из оболочки / node script). Любые идеи?

Ответ 1

Вы можете сделать это, но вам нужно будет использовать расширения Chrome.

Расширения Chrome имеют много безопасности в стиле песочницы. Связь между расширением Chrome и веб-страницей - это многоэтапный процесс. Здесь самое краткое объяснение, которое я могу предложить с полным рабочим примером в конце:

  • Расширение Chrome имеет полный доступ к хром. * API, но расширение Chrome не может напрямую связываться с веб-страницей JS, и веб-страница JS не может напрямую взаимодействовать с расширением Chrome.

  • Чтобы устранить разрыв между расширением Chrome и веб-страницей, вам необходимо использовать content script. Содержимое script - это, по сути, JavaScript, который вводится в области window целевой веб-страницы. Содержимое script не может вызывать функции и не использовать переменные, созданные на веб-странице JS, , но они совместно используют доступ к тем же DOM и, следовательно, к событиям.

  • Поскольку прямой доступ к переменным и вызывающим функциям не разрешен, единственный способ, которым может взаимодействовать веб-страница и контент script, - это запустить настраиваемые события.

Например, если я хочу передать сообщение из расширения 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. Теперь, когда вы можете отправить сообщение из содержимого script на веб-страницу, теперь вам нужно, чтобы расширение Chrome собирало всю необходимую вам информацию о сети. Вы можете выполнить это через пару разных модулей, но самым простым вариантом является модуль webRequest (см. background.js ниже).

`5. Используйте сообщение, передающее, чтобы передать информацию о веб-запросах в контент script, а затем перейти на веб-страницу JavaScript.

Визуально, вы можете думать об этом так:

Chrome extensions and content scripts

Полный рабочий пример:

Первые три файла содержат расширение Google Chrome, а последний файл - это файл HTML, который вы должны загрузить в веб-пространство http://.

icon.png

Используйте любой PNG файл 16x16.

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
}

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>