是否可以创建修改 HTTP 响应正文的 Chrome 扩展程序?
我查看了Chrome Extension APIs,但我没有找到任何可以做到这一点的东西。
是否可以创建修改 HTTP 响应正文的 Chrome 扩展程序?
我查看了Chrome Extension APIs,但我没有找到任何可以做到这一点的东西。
通常,您无法使用标准 Chrome 扩展 API 更改 HTTP 请求的响应正文。
在104058 请求此功能:WebRequest API:允许扩展编辑响应正文。为问题加注星标以获取更新通知。
如果要编辑 known 的响应正文,请XMLHttpRequest
通过内容脚本注入代码XMLHttpRequest
以使用自定义(全功能)构造函数覆盖默认构造函数,该构造函数在触发真实事件之前重写响应。确保您的 XMLHttpRequest 对象与 Chrome 的内置对象完全兼容XMLHttpRequest
,否则 AJAX 繁重的网站将会崩溃。
在其他情况下,您可以使用chrome.webRequest
或chrome.declarativeWebRequest
API 将请求重定向到data:
-URI。与 XHR 方法不同,您不会获得请求的原始内容。实际上,请求永远不会到达服务器,因为重定向只能在实际请求发送之前完成。如果您重定向main_frame
请求,用户将看到data:
-URI 而不是请求的 URL。
我刚刚发布了一个可以做到这一点的 Devtools 扩展 :)
它被称为篡改,它基于mitmproxy,它允许您查看当前选项卡发出的所有请求,修改它们并在下次刷新时提供修改后的版本。
这是一个相当早期的版本,但它应该与 OS X 和 Windows 兼容。让我知道它是否不适合你。
你可以在这里得到它http://dutzi.github.io/tamper/
这是如何工作的
正如@Xan 在下面评论的那样,该扩展通过 Native Messaging 与扩展mitmproxy的 python 脚本进行通信。
该扩展使用 列出所有请求chrome.devtools.network.onRequestFinished
。
当您单击请求时,它会使用请求对象的getContent()
方法下载其响应,然后将该响应发送到将其保存在本地的 python 脚本。
然后它在编辑器中打开文件(call
用于 OSX 或subprocess.Popen
Windows)。
python 脚本使用 mitmproxy 侦听通过该代理进行的所有通信,如果它检测到对已保存文件的请求,它会提供已保存的文件。
我使用 Chrome 的代理 API(特别是chrome.proxy.settings.set()
)将 PAC 设置为代理设置。该 PAC 文件将所有通信重定向到 python 脚本的代理。
mitmproxy 最大的优点之一是它还可以修改 HTTPs 通信。所以你也有:)
就像@Rob w 说的那样,我已经覆盖XMLHttpRequest
,这是修改任何站点中的任何 XHR 请求的结果(就像透明修改代理一样工作):
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);
};
例如,Tampermonkey 可以成功地使用此代码对任何站点进行任何修改:)
是的。可以使用chrome.debugger
API,它授予对Chrome DevTools 协议的扩展访问权限,该协议通过其网络 API支持 HTTP 拦截和修改。
此解决方案是由对 Chrome 问题 487422 的评论提出的:
对于任何想要目前可行的替代方案的人,您可以
chrome.debugger
在背景/事件页面中使用以附加到您想要收听的特定选项卡(或者如果可能的话,附加到所有选项卡,尚未亲自测试所有选项卡) ,然后使用调试协议的网络API。唯一的问题是标签的视口顶部会出现通常的黄色条,除非用户在
chrome://flags
.
首先,将调试器附加到目标:
chrome.debugger.getTargets((targets) => {
let target = /* Find the target. */;
let debuggee = { targetId: target.id };
chrome.debugger.attach(debuggee, "1.2", () => {
// TODO
});
});
接下来,发送Network.setRequestInterceptionEnabled
命令,这将启用网络请求的拦截:
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 现在将开始发送Network.requestIntercepted
事件。为他们添加一个监听器:
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
}
});
});
在监听器中,params.request
将是对应的Request
对象。
发送响应Network.continueInterceptedRequest
:
rawResponse
.params.interceptionId
_interceptionId
请注意,我根本没有测试过这些。
虽然 Safari 内置了此功能,但到目前为止我发现的 Chrome 的最佳解决方法是使用赛普拉斯的拦截功能。它干净地允许我在 Chrome 中存根 HTTP 响应。cy.intercept
然后我调用cy.visit(<URL>)
它,它会拦截并为访问的页面发出的特定请求提供一个存根响应。这是一个例子:
cy.intercept('GET', '/myapiendpoint', {
statusCode: 200,
body: {
myexamplefield: 'Example value',
},
})
cy.visit('http://localhost:8080/mytestpage')
注意:您可能还需要配置 Cypress以禁用某些特定于 Chrome 的安全设置。
Chrome 不提供任何 API 来修改响应正文。Chrome WebRequest API和DeclarativeNetRequest API都无法做到这一点。
Requestly 桌面应用程序提供了创建修改 HTTP 响应规则的功能,然后您可以在任何浏览器中使用它。这是演示视频。这是执行此操作的步骤
您可以通过 3 种方式定义自定义响应
不仅如此,您还可以使用这种方法将 HTTP 状态代码更改为 400 或 500 。
也可以使用Requestly Chrome Extension来修改仅由 XHR/fetch 触发的 HTTP 请求的响应。这是使用 Chrome 扩展的演示视频
由于 Chrome 不提供任何 API,Requestly 会覆盖 XHR 并获取原型对象以挂钩自定义实现,您将获得您在 Requestly 响应修改规则中定义的响应。您可以在docs中阅读有关它的更多信息。
PS:我建立了请求