¿Es posible crear una extensión de Chrome que modifique los cuerpos de respuesta HTTP?
He buscado en las API de extensión de Chrome , pero no he encontrado nada para hacer esto.
google-chrome-extension
capitán dragón
fuente
fuente
webRequest.filterResponseData()
. Desafortunadamente, esta es una solución solo para Firefox.Respuestas:
En general, no puede cambiar el cuerpo de respuesta de una solicitud HTTP utilizando las API de extensión estándar de Chrome.
Esta función se solicita en 104058: API WebRequest: permitir que la extensión edite el cuerpo de la respuesta . Destaca el problema para recibir notificaciones de actualizaciones.
Si desea editar el cuerpo de la respuesta para un conocido
XMLHttpRequest
, inyecte código a través de una secuencia de comandos de contenido para anular elXMLHttpRequest
constructor predeterminado con uno personalizado (con todas las funciones) que reescribe la respuesta antes de activar el evento real. Asegúrese de que su objeto XMLHttpRequest sea totalmente compatible con elXMLHttpRequest
objeto integrado de Chrome , o los sitios con mucho AJAX se romperán.En otros casos, puede utilizar las API
chrome.webRequest
ochrome.declarativeWebRequest
para redirigir la solicitud adata:
-URI. A diferencia del enfoque XHR, no obtendrá el contenido original de la solicitud. En realidad, la solicitud nunca llegará al servidor porque la redirección solo se puede realizar antes de que se envíe la solicitud real. Y si redirige unamain_frame
solicitud, el usuario verá ladata:
-URI en lugar de la URL solicitada.fuente
data:text...
?Acabo de lanzar una extensión de Devtools que hace precisamente eso :)
Se llama tamper, se basa en mitmproxy y le permite ver todas las solicitudes realizadas por la pestaña actual, modificarlas y entregar la versión modificada la próxima vez que actualice.
Es una versión bastante temprana, pero debería ser compatible con OS X y Windows. Avísame si no te funciona.
Puedes conseguirlo aquí http://dutzi.github.io/tamper/
Como funciona esto
Como @Xan comentó a continuación, la extensión se comunica a través de la mensajería nativa con un script de Python que extiende mitmproxy .
La extensión enumera todas las solicitudes que utilizan
chrome.devtools.network.onRequestFinished
.Cuando haces clic en una de las solicitudes, descarga su respuesta utilizando el
getContent()
método del objeto de solicitud y luego envía esa respuesta al script de Python que la guarda localmente.Luego abre el archivo en un editor (usando
call
para OSX osubprocess.Popen
para Windows).La secuencia de comandos de Python usa mitmproxy para escuchar toda la comunicación realizada a través de ese proxy, si detecta una solicitud de un archivo que se guardó, sirve el archivo que se guardó en su lugar.
Usé la API de proxy de Chrome (específicamente
chrome.proxy.settings.set()
) para configurar un PAC como configuración de proxy. Ese archivo PAC redirige toda la comunicación al proxy del script de Python.Una de las mejores cosas de mitmproxy es que también puede modificar la comunicación HTTP. Entonces tienes eso también :)
fuente
Si. Es posible con la
chrome.debugger
API, que otorga acceso de extensión al Protocolo Chrome DevTools , que admite la interceptación y modificación HTTP a través de su API de red .Esta solución fue sugerida por un comentario sobre el problema de Chrome 487422 :
Primero, adjunte un depurador al destino:
chrome.debugger.getTargets((targets) => { let target = /* Find the target. */; let debuggee = { targetId: target.id }; chrome.debugger.attach(debuggee, "1.2", () => { // TODO }); });
A continuación, envíe el
Network.setRequestInterceptionEnabled
comando, que permitirá la interceptación de solicitudes de red:chrome.debugger.getTargets((targets) => { let target = /* Find the target. */; let debuggee = { targetId: target.id }; chrome.debugger.attach(debuggee, "1.2", () => { chrome.debugger.sendCommand(debuggee, "Network.setRequestInterceptionEnabled", { enabled: true }); }); });
Chrome ahora comenzará a enviar
Network.requestIntercepted
eventos. Agrega un oyente para ellos:chrome.debugger.getTargets((targets) => { let target = /* Find the target. */; let debuggee = { targetId: target.id }; chrome.debugger.attach(debuggee, "1.2", () => { chrome.debugger.sendCommand(debuggee, "Network.setRequestInterceptionEnabled", { enabled: true }); }); chrome.debugger.onEvent.addListener((source, method, params) => { if(source.targetId === target.id && method === "Network.requestIntercepted") { // TODO } }); });
En el oyente,
params.request
estará elRequest
objeto correspondiente .Envía la respuesta con
Network.continueInterceptedRequest
:rawResponse
.params.interceptionId
comointerceptionId
.Tenga en cuenta que no he probado nada de esto, en absoluto.
fuente
setRequestInterceptionEnabled
método parece no estar incluido en el protocolo DevTools v1.2, y no puedo encontrar una manera de adjuntarlo con la última versión (punta del árbol) en su lugar.chrome.debugger.sendCommand(debuggee, "Network.setRequestInterceptionEnabled", { enabled: true });
falla con 'Network.setRequestInterceptionEnabled' no se encontró 'Como dijo @Rob w, he anulado
XMLHttpRequest
y este es el resultado de la modificación de cualquier solicitud XHR en cualquier sitio (que funciona como un proxy de modificación transparente):var _open = XMLHttpRequest.prototype.open; window.XMLHttpRequest.prototype.open = function (method, URL) { var _onreadystatechange = this.onreadystatechange, _this = this; _this.onreadystatechange = function () { // catch only completed 'api/search/universal' requests if (_this.readyState === 4 && _this.status === 200 && ~URL.indexOf('api/search/universal')) { try { ////////////////////////////////////// // THIS IS ACTIONS FOR YOUR REQUEST // // EXAMPLE: // ////////////////////////////////////// var data = JSON.parse(_this.responseText); // {"fields": ["a","b"]} if (data.fields) { data.fields.push('c','d'); } // rewrite responseText Object.defineProperty(_this, 'responseText', {value: JSON.stringify(data)}); /////////////// END ////////////////// } catch (e) {} console.log('Caught! :)', method, URL/*, _this.responseText*/); } // call original callback if (_onreadystatechange) _onreadystatechange.apply(this, arguments); }; // detect any onreadystatechange changing Object.defineProperty(this, "onreadystatechange", { get: function () { return _onreadystatechange; }, set: function (value) { _onreadystatechange = value; } }); return _open.apply(_this, arguments); };
por ejemplo, este código puede ser utilizado con éxito por Tampermonkey para realizar modificaciones en cualquier sitio :)
fuente
response
más nuevo en lugar deresponseText
, por lo que todo lo que tiene que hacer es cambiar Object.defineProperty para usarresponse
en su lugar