0

我正在编写一个 Electron 应用程序,它创建一个BrowserWindow. 我想捕获一些发送到服务器的请求,我还想响应那里的请求。使用 Electron WebRequestapi 我无法得到响应,所以在网上搜索并发现我可以以编程方式附加调试器。

我使用以下代码附加调试器,并且几乎所有响应都正确。但是对于一个更大的请求,我无法得到响应。我收到一个错误

Error: No resource with given identifier found

如果我启动 DevTools 并导航到该请求,我也无法得到响应:Failed to load response data. 如果我在下面的代码中注释掉,DevTools 中的响应会正确显示。

请注意,这只发生在一个返回大约 1MB 响应的特定请求中。对于所有其他请求,我可以使用getResponseData().

const dbg = win.webContents.debugger

var getResponseData = async (reqId) => {
    const res = await dbg.sendCommand("Network.getResponseBody", {requestId: reqId});
    return res.body
}

try {
    dbg.attach('1.3')
    dbg.sendCommand('Network.enable')
} catch (err) {
    console.log('Debugger attach failed : ', err)
}

dbg.on('detach', async (event, reason) => {
    console.log('Debugger detached due to : ', reason)
})

dbg.on('message', (e, m, p) => {
    if (m === 'Network.requestWillBeSent') {
        if (p.request.url === someURL) {
            const j = JSON.parse(p.request.postData)
            console.log("req " + p.requestId)
            global.webReqs[p.requestId] = { reqData: j}
        }
    } else if (m === 'Network.loadingFinished') {
        if (p.requestId in global.webReqs) {
            console.log("res " + p.requestId)
            getResponseData(p.requestId).then(res => {
                console.log(res.slice(0,60))
            }).catch(err => {
                console.error(err)
            })
        }
    }
});

简短更新 此特定请求的事件堆栈如下,其中13548.212简单的 requestId

Network.requestWillBeSentExtraInfo 13548.212
Network.requestWillBeSent 13548.212
Network.responseReceivedExtraInfo 13548.212
Network.responseReceived 13548.212
Network.dataReceived 13548.212 [repeated 135 times]
...
Network.loadingFinished 13548.212

4

1 回答 1

1

看起来我找到了解决方案。这是一种解决方法,但它确实有效。我没用Network.getResponseBody。我用过Fetchhttps://chromedevtools.github.io/devtools-protocol/tot/Fetch)。

要使用它,需要订阅与模式匹配的响应。然后你可以对Fetch.requestPaused事件做出反应。在此期间,您可以直接访问请求并间接访问响应。Fetch.getResponseBody以正确的方式获得响应调用requestId。还记得发送Fetch.continueRequest

请求暂停,直到客户端以 continueRequest、failRequest 或fulfillRequest 之一响应

https://chromedevtools.github.io/devtools-protocol/tot/Fetch/#event-requestPaused

   dbg.sendCommand('Fetch.enable', {
            patterns: [
                { urlPattern: interestingURLpattern, requestStage: "Response" }
            ]})

   var getResponseJson = async (requestId) => {
         const res = await dbg.sendCommand("Fetch.getResponseBody", {requestId: requestId})
         return JSON.parse(res.base64Encoded ? Buffer.from(res.body, 'base64').toString() : res.body)
     }
    dbg.on('message', (e, m, p) => {
        if(m === 'Fetch.requestPaused') {
            var reqJson = JSON.parse(p.request.postData)
            var resJson = await getResponseJson(p.requestId)
            ...

            await dbg.sendCommand("Fetch.continueRequest", {requestId: p.requestId})
        }
    });
于 2021-02-08T19:53:57.267 回答