【问题标题】:Chrome extension: intercept HTTP ResponseChrome 扩展:拦截 HTTP 响应
【发布时间】:2019-03-11 04:19:41
【问题描述】:

我看到很多页面都在讨论如何从站点接收 HTTP 响应。我正在尝试这个:Chrome Extension - How to get HTTP Response Body? 没有可执行程序...这是我的代码:

manifest.json:

{
  "manifest_version": 2,

  "name": "Extension Name",
  "description": "Some Desc.",
  "version": "1.1",

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "index.html"
  },
  "permissions": [
    "activeTab",
    "storage",
    "tabs",
    "https://*.google.com/"
  ],
  "content_scripts": [
    {
      "matches": ["https://*.google.com/"],
      "run_at": "document_start",
      "js": ["contentscript.js", "inject.js"]
    }
  ],
  "web_accessible_resources": ["injected.js"]
}

index.html:

<html>

    <head>
        <script src="contentscript.js"></script>
    </head>

    <body>
            <p>HTTP INTERCEPTOR</p>
    </body>

</html>

injected.js:

(function(xhr) {
    console.log('injeced file');

    var XHR = XMLHttpRequest.prototype;

    var open = XHR.open;
    var send = XHR.send;
    var setRequestHeader = XHR.setRequestHeader;

    XHR.open = function(method, url) {
        this._method = method;
        this._url = url;
        this._requestHeaders = {};
        this._startTime = (new Date()).toISOString();

        return open.apply(this, arguments);
    };

    XHR.setRequestHeader = function(header, value) {
        this._requestHeaders[header] = value;
        return setRequestHeader.apply(this, arguments);
    };

    XHR.send = function(postData) {

        this.addEventListener('load', function() {
            var endTime = (new Date()).toISOString();

            var myUrl = this._url ? this._url.toLowerCase() : this._url;
            if(myUrl) {

                if (postData) {
                    if (typeof postData === 'string') {
                        try {
                            // here you get the REQUEST HEADERS, in JSON format, so you can also use JSON.parse
                            this._requestHeaders = postData;    
                        } catch(err) {
                            console.log('Request Header JSON decode failed, transfer_encoding field could be base64');
                            console.log(err);
                        }
                    } else if (typeof postData === 'object' || typeof postData === 'array' || typeof postData === 'number' || typeof postData === 'boolean') {
                            // do something if you need
                    }
                }

                // here you get the RESPONSE HEADERS
                var responseHeaders = this.getAllResponseHeaders();

                if ( this.responseType != 'blob' && this.responseText) {
                    // responseText is string or null
                    try {

                        // here you get RESPONSE TEXT (BODY), in JSON format, so you can use JSON.parse
                        var arr = this.responseText;

                        // printing url, request headers, response headers, response body, to console

                        console.log(this._url);
                        console.log(JSON.parse(this._requestHeaders));
                        console.log(responseHeaders);
                        console.log(JSON.parse(arr));                        

                    } catch(err) {
                        console.log("Error in responseType try catch");
                        console.log(err);
                    }
                }

            }
        });

        return send.apply(this, arguments);
    };

})(XMLHttpRequest);

inject.js 我设置了一个超时,这样我就可以启用调试器了:

/**
 * code in inject.js
 * added "web_accessible_resources": ["injected.js"] to manifest.json
 */

setTimeout(function() {
    var s = document.createElement('script');
    s.src = chrome.extension.getURL('injected.js');
    s.onload = function() {
        this.remove();
        console.log('remove');
    };
    (document.head || document.documentElement).appendChild(s);
}, 10000);

为什么代码没有注入https://www.google.com/?检查 DOM 我没有看到代码......代码运行并且 XHR 是 setrtes 但方法 open、setRequestHeader 和 send 永远不会被收集。

【问题讨论】:

  • this 不是您获得代码的问题吗?也许您应该在那里发表评论,询问inject.js 中的内容。
  • @Barmar 已发布。谢谢,但我不认为这是问题所在。

标签: javascript google-chrome google-chrome-extension http-headers http-get


【解决方案1】:

代码来自我的回答here。 在这种情况下,Content Script 用于与 injection.js 进行通信。

示例代码如下:

/**
 * Content script currently only used to communicate extension state on off message to injected.js
 * Sends back response to extension (popup.js) after sending message to injected.js
 */
$(function(){

    // localStorage is different from chrome.storage
    // localStorage for injected script, and chrome.storage for extension script (popup.js) and contentscript.js

    chrome.storage.sync.get("state", function (data) {

        if (typeof data.state === 'undefined') {
            chrome.storage.sync.set({"state": "on"}, function() {});    // async
        }

        console.log("Content Script State: " + data.state);
    });

    // message from extension script to this content script.
    // will be used to receive enable disable messages
    // sends response in 'status' variable
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
        console.log(sender.tab ?
                    "content script receiving message from a content script:" + sender.tab.url :
                    "content script receiving message from the extension");

        if (request.toggle === true) {
            chrome.storage.sync.set({"state": "on"}, function() { console.log("Content Script State Updated: on"); });  // async
            var data = {
                app_state: "on"
            };
            document.dispatchEvent(new CustomEvent("app_state_message", {detail: data}));
            // cannot return state in function since above .set is async and popup.js does not receive the response
            sendResponse({state: "on"});
        } else if (request.toggle === false) {
            chrome.storage.sync.set({"state": "off"}, function() { console.log("Content Script State Updated: off"); });    // async
            var data = {
                app_state: "off"
            };
            document.dispatchEvent(new CustomEvent("app_state_message", {detail: data}));
            sendResponse({state: "off"});
        } else {
            sendResponse({state: "error"});
        }

    });

});

请在Content Scripts 上阅读更多信息。希望你觉得这很有用。

【讨论】:

  • 感谢您的回答!它已经有很大的帮助了。我不确定您是否收到通知-我对这个问题给予了赏金,因为我在将您的两个答案都转换为可重复的示例时遇到了麻烦。我不想偷走您的任何宝贵时间,但我只是想自己解决 Chrome 扩展程序的新手。这就是为什么我决定在赏金方面带来“努力”。
  • 不好意思再次打扰,但有机会吗?
  • 我已经有一年没有研究 chrome 扩展了。您需要什么帮助?
  • 感谢您的回答。是否有任何机会您仍然拥有可复制的应用程序形式,该应用程序捕获包括正文在内的网络请求并在内容脚本中进行处理。也许是您使用代码的旧扩展?非常感谢!
  • @ThanksGuys 我可以将我正在开发的扩展程序的整个代码上传到 Github 并给你链接。告诉我
猜你喜欢
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 2019-01-23
相关资源
最近更新 更多