1. ホーム
  2. javascript

[解決済み] Chromeの拡張機能です。Network.getResponseBody を実行しようとすると、「指定された識別子を持つリソースが見つかりません」と表示される。

2022-02-15 16:02:52

質問

あるサイトのHTTPレスポンスを取得するChrome Extensionを書いています。レスポンスボディを取得するためにデバッガを使用しようとしています。

var gCurrentTab;

chrome.debugger.onEvent.addListener(function (source, method, params) {
        if (gCurrentTab.id != source.tabId) {
            return;
        }
        if (method == "Network.loadingFinished") {
            var tabId = source.tabId;
            var requestId = params.requestId;
            chrome.debugger.sendCommand(
                source,
                "Network.getResponseBody",
                {"requestId": requestId},
                function (body) {
                    console.log(body);
                    chrome.debugger.detach(source);
                });
        }
    }
);

chrome.webRequest.onBeforeRequest.addListener(function (details) {
        var url = details.url;
        if (url.indexOf('/mypage') >= 0) {
            chrome.tabs.query({
                currentWindow: true,
                active: true
            }, function (tabs) {
                gCurrentTab = tabs[0];
                chrome.debugger.attach({
                    tabId: gCurrentTab.id
                }, "1.0", function () {
                    chrome.debugger.sendCommand({
                        tabId: gCurrentTab.id
                    }, "Network.enable");
                });
            });
        }
    },
    {urls: []}, ["requestBody", "blocking"]);

しかし、私はいつも

debugger.sendCommand の実行中にチェックされていない runtime.lastError が発生しました。{"code":-32000,"message":"No resource with given identifier found"} というエラーが発生しました。 at chrome-extension://ikphgobkghdkjkfplgokmapjlbdfeegl/background.js:11:29

エラーが発生し、本体が未定義になっています。

なぜこのようなことが起こるのか、どなたかおわかりになりますか?ありがとうございます。

解決方法は?

ウェブサイトが多くのレスポンスを送信するため、このコードでは私が望む以外の別のリクエストが表示され、デバッガが切り離されるため、結果を得ることができないのです。

これを解決するには、デバッガーを1つだけにして、デタッチしないか、安全なときだけデタッチするようにすればいい。

var gAttached = false;
var gRequests = [];
var gObjects = [];

chrome.debugger.onEvent.addListener(function (source, method, params) {
        if (method == "Network.requestWillBeSent") {
            // If we see a url need to be handled, push it into index queue
            var rUrl = params.request.url;
            if (getTarget(rUrl) >= 0) {
                gRequests.push(rUrl);
            }
        }
        if (method == "Network.responseReceived") {
            // We get its request id here, write it down to object queue
            var eUrl = params.response.url;
            var target = getTarget(eUrl);
            if (target >= 0) {
                gObjects.push({
                    requestId: params.requestId,
                    target: target,
                    url: eUrl
                });
            }
        }
        if (method == "Network.loadingFinished" && gObjects.length > 0) {
            // Pop out the request object from both object queue and request queue
            var requestId = params.requestId;
            var object = null;
            for (var o in gObjects) {
                if (requestId == gObjects[o].requestId) {
                    object = gObjects.splice(o, 1)[0];
                    break;
                }
            }
            // Usually loadingFinished will be immediately after responseReceived
            if (object == null) {
                console.log('Failed!!');
                return;
            }
            gRequests.splice(gRequests.indexOf(object.url), 1);
            chrome.debugger.sendCommand(
                source,
                "Network.getResponseBody",
                {"requestId": requestId},
                function (response) {
                    if (response) {
                        dispatch(source.tabId, object.target, JSON.parse(response.body));
                    } else {
                        console.log("Empty response for " + object.url);
                    }
                    // If we don't have any request waiting for response, re-attach debugger
                    // since without this step it will lead to memory leak.
                    if (gRequests.length == 0) {
                        chrome.debugger.detach({
                            tabId: source.tabId
                        }, function () {
                            chrome.debugger.attach({
                                tabId: source.tabId
                            }, "1.0", function () {
                                chrome.debugger.sendCommand({
                                    tabId: source.tabId
                                }, "Network.enable");
                            });
                        });
                    }
                });
        }
    }
);

var initialListener = function (details) {
    if (gAttached) return;  // Only need once at the very first request, so block all following requests
    var tabId = details.tabId;
    if (tabId > 0) {
        gAttached = true;
        chrome.debugger.attach({
            tabId: tabId
        }, "1.0", function () {
            chrome.debugger.sendCommand({
                tabId: tabId
            }, "Network.enable");
        });
        // Remove self since the debugger is attached already
        chrome.webRequest.onBeforeRequest.removeListener(initialListener);
    }
};

// Attach debugger on startup
chrome.webRequest.onBeforeRequest.addListener(initialListener, {urls: ["<all_urls>"]}, ["blocking"]);

// Filter if the url is what we want
function getTarget(url) {
    for (var i in TARGETS) {
        var target = TARGETS[i];
        if (url.match(target.url)) {
            return i;
        }
    }
    return -1;
}

const TARGETS = [
    {url: '/path1', desc: 'target1'},
    {url: '/path2', desc: 'target2'}
]