Расширение Chrome - Как получить тело ответа HTTP?
Кажется, что это трудная проблема (или невозможная?).
Я хочу получить и прочитать HTTP-ответ, вызванный HTTP-запросом в браузере, при просмотре фона Chrome Extension script.
Таким образом мы можем получить тело запроса HTTP.
chrome.webRequest.onBeforeRequest.addListener(function(data){
// data contains request_body
},{'urls':[]},['requestBody']);
Я также проверил эти stackoverflows
Есть ли какой-нибудь умный способ получить тело ответа HTTP в расширении Chrome?
Ответы
Ответ 1
Я не могу найти лучший способ, чем этот ответ.
Расширение Chrome для чтения HTTP-ответа
В ответе рассказывалось, как получить заголовки ответа и отобразить его на другой странице. Но в obj ответа нет информации о теле (см. event-responseReceived). Если вы хотите получить ответ body без другой страницы, попробуйте это.
var currentTab;
var version = "1.0";
chrome.tabs.query( //get current Tab
{
currentWindow: true,
active: true
},
function(tabArray) {
currentTab = tabArray[0];
chrome.debugger.attach({ //debug at current tab
tabId: currentTab.id
}, version, onAttach.bind(null, currentTab.id));
}
)
function onAttach(tabId) {
chrome.debugger.sendCommand({ //first enable the Network
tabId: tabId
}, "Network.enable");
chrome.debugger.onEvent.addListener(allEventHandler);
}
function allEventHandler(debuggeeId, message, params) {
if (currentTab.id != debuggeeId.tabId) {
return;
}
if (message == "Network.responseReceived") { //response return
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
}, function(response) {
// you get the response body here!
// you can close the debugger tips by:
chrome.debugger.detach(debuggeeId);
});
}
}
Я думаю, это достаточно полезно для меня, и вы можете использовать chrome.debugger.detach(debuggeeId)
, чтобы закрыть уродливый совет.
извините, Мэйби, не полезно... ^ ^
Ответ 2
Это определенно то, что не поставляется из коробки экосистемой Chrome Extension. Но я мог бы найти несколько способов обойти это, но оба имеют свои недостатки.
Первый способ:
- Используйте скрипт контента, чтобы внедрить наш собственный скрипт.
- Используйте пользовательский сценарий для расширения собственных методов XHR для чтения ответа.
- Добавьте ответ на DOM веб-страницы внутри скрытого (не
display: none
) элемента. - Используйте скрипт содержимого, чтобы прочитать скрытый ответ.
Второй способ - создать расширение DevTools, которое является единственным расширением, предоставляющим API для чтения каждого запроса.
Я подробно описал оба метода в своем блоге .
Дайте мне знать, если у вас возникнут какие-либо проблемы! :)
Ответ 3
Теперь есть возможность расширения Chrome Developer Tools, и пример кода можно посмотреть здесь: сообщение в блоге.
Вкратце, вот адаптация его примера кода:
chrome.devtools.network.onRequestFinished.addListener(request => {
request.getContent((body) => {
if (request.request && request.request.url) {
if (request.request.url.includes('facebook.com')) {
//continue with custom code
var bodyObj = JSON.parse(body);//etc.
}
}
});
});
Ответ 4
// manifest - "permissions":["tabs","webRequest","webRequestBlocking","<all_urls>","debugger"]
var check_attached_tabs={};
chrome.webRequest.onBeforeRequest.addListener
(
function callOnBeforeRequest(details){
//if(details.type!=='main_frame'){return;}
var tabId=details.tabId;
if(tabId==-1){return;}
var check_atach=false;
if(!(tabId in check_attached_tabs)){
check_attached_tabs[tabId]={};
}
if(check_attached_tabs[tabId].attached===true){
check_atach=true;
}
if(check_atach==false){
chrome.debugger.attach({ // chrome.debugger.attach must be declared before all requests begin
tabId: tabId
}, '1.0', function(){
// Point for errors
if('lastError' in chrome.runtime){
//error when you open a new tab will appear (+) without reference
if( chrome.runtime.lastError.message=='Cannot access a chrome:// URL'){
return;
}
console.log( chrome.runtime.lastError );
}
//----
//check_attached_tabs[tabId].attached=true;
chrome.debugger.sendCommand({ //activaiton networks trafic for debugger
tabId: tabId
}, "Network.enable");
check_attached_tabs[tabId].attached=true;
console.log('attach');
});
if(!('events' in check_attached_tabs[tabId])){
check_attached_tabs[tabId].events={
attach:function call(source, method, params){
// point for filtered request
if ( tabId != source.tabId) {
return;
}
//Point for commands - https://chromedevtools.github.io/devtools-protocol/tot/Network
if (method == "Network.loadingFinished") {
//console.log(source, method, params);
// Point for errors
chrome.debugger.sendCommand({
tabId: source.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
}, function(response) {
// Point for errors
if('lastError' in chrome.runtime){
//console.log( chrome.runtime.lastError );
if( chrome.runtime.lastError.message=='{"code":-32000,"message":"No resource with given identifier found"}'){
//will error occur when the query returns nothing
return;
}
}
//point response body for result ;
console.log(response);
});
}
},
detach:function(source,reason){
if(source.tabId in check_attached_tabs){
console.log('detach');
chrome.debugger.onEvent.removeListener(check_attached_tabs[source.tabId].events.attach);
chrome.debugger.onDetach.removeListener(check_attached_tabs[source.tabId].events.detach);
delete check_attached_tabs[source.tabId];
}
}
}
chrome.debugger.onEvent.addListener(check_attached_tabs[tabId].events.attach);
chrome.debugger.onDetach.addListener(check_attached_tabs[tabId].events.detach);
}
}
},
{urls:['<all_urls>']},
["requestBody"]
);
chrome.tabs.onRemoved.addListener
(
function(tabId) {
chrome.debugger.getTargets(function(targets){
for(var target of targets){
if(target.tabId==tabId && target.attached==true){
chrome.debugger.detach( {tabId:tabId}, function(){});
break;
}
}
});
}
);
chrome.runtime.onSuspend.addListener
(
function(){
for(var tabId in check_attached_tabs){
chrome.debugger.detach( {tabId:tabId}, function(){});
}
}
);