Có thể tạo tiện ích mở rộng Chrome sửa đổi các phần tử phản hồi HTTP không?
Tôi đã xem xét các API tiện ích mở rộng của Chrome , nhưng tôi không tìm thấy bất kỳ thứ gì để thực hiện việc này.
Có thể tạo tiện ích mở rộng Chrome sửa đổi các phần tử phản hồi HTTP không?
Tôi đã xem xét các API tiện ích mở rộng của Chrome , nhưng tôi không tìm thấy bất kỳ thứ gì để thực hiện việc này.
webRequest.filterResponseData()
. Thật không may, đây là giải pháp chỉ dành cho Firefox.
Câu trả lời:
Nói chung, bạn không thể thay đổi nội dung phản hồi của một yêu cầu HTTP bằng các API tiện ích mở rộng Chrome tiêu chuẩn.
Tính năng này đang được yêu cầu tại 104058: API WebRequest: cho phép tiện ích mở rộng chỉnh sửa nội dung phản hồi . Gắn dấu sao vấn đề để nhận thông báo về các bản cập nhật.
Nếu bạn muốn chỉnh sửa nội dung phản hồi cho một mã đã biết XMLHttpRequest
, hãy chèn mã qua tập lệnh nội dung để ghi đè phương thức XMLHttpRequest
khởi tạo mặc định bằng phương thức xây dựng tùy chỉnh (đầy đủ tính năng) ghi lại phản hồi trước khi kích hoạt sự kiện thực. Đảm bảo rằng đối tượng XMLHttpRequest của bạn hoàn toàn tuân thủ với đối tượng tích hợp sẵn của Chrome XMLHttpRequest
, nếu không các trang web nặng AJAX sẽ bị hỏng.
Trong các trường hợp khác, bạn có thể sử dụng chrome.webRequest
hoặc chrome.declarativeWebRequest
các API để chuyển hướng yêu cầu đến data:
-URI. Không giống như cách tiếp cận XHR, bạn sẽ không nhận được nội dung ban đầu của yêu cầu. Trên thực tế, yêu cầu sẽ không bao giờ được gửi đến máy chủ vì việc chuyển hướng chỉ có thể được thực hiện trước khi yêu cầu thực sự được gửi đi. Và nếu bạn chuyển hướng một main_frame
yêu cầu, người dùng sẽ thấy data:
-URI thay vì URL được yêu cầu.
data:text...
gì?
Tôi vừa phát hành một tiện ích mở rộng Devtools làm được điều đó :)
Nó được gọi là giả mạo, dựa trên mitmproxy và nó cho phép bạn xem tất cả các yêu cầu được thực hiện bởi tab hiện tại, sửa đổi chúng và phục vụ phiên bản đã sửa đổi vào lần tiếp theo bạn làm mới.
Đây là một phiên bản khá sớm nhưng nó phải tương thích với OS X và Windows. Hãy cho tôi biết nếu nó không hiệu quả với bạn.
Bạn có thể lấy nó tại đây http://dutzi.github.io/tamper/
Cách thức hoạt động
Như @Xan đã nhận xét bên dưới, tiện ích mở rộng giao tiếp thông qua Nhắn tin gốc với một tập lệnh python mở rộng mitmproxy .
Tiện ích mở rộng liệt kê tất cả các yêu cầu sử dụng chrome.devtools.network.onRequestFinished
.
Khi bạn nhấp vào các yêu cầu, nó sẽ tải xuống phản hồi của nó bằng cách sử dụng getContent()
phương thức của đối tượng yêu cầu , sau đó gửi phản hồi đó đến tập lệnh python để lưu nó cục bộ.
Sau đó, nó mở tệp trong trình chỉnh sửa (sử dụng call
cho OSX hoặc subprocess.Popen
cho windows).
Tập lệnh python sử dụng mitmproxy để lắng nghe tất cả các giao tiếp được thực hiện thông qua proxy đó, nếu nó phát hiện yêu cầu đối với tệp đã được lưu, nó sẽ phân phối tệp đã được lưu thay thế.
Tôi đã sử dụng API proxy của Chrome (cụ thể chrome.proxy.settings.set()
) để đặt PAC làm cài đặt proxy. Tệp PAC đó chuyển hướng tất cả giao tiếp đến proxy của tập lệnh python.
Một trong những điều tuyệt vời nhất về mitmproxy là nó cũng có thể sửa đổi giao tiếp HTTP. Vì vậy, bạn cũng có cái đó :)
Đúng. Có thể thực hiện được với chrome.debugger
API, cấp quyền truy cập mở rộng vào Giao thức Chrome DevTools , hỗ trợ chặn và sửa đổi HTTP thông qua API mạng của nó .
Giải pháp này được đề xuất bởi một nhận xét trên Chrome Issue 487422 :
Đối với bất kỳ ai muốn có một giải pháp thay thế có thể thực hiện được vào lúc này, bạn có thể sử dụng
chrome.debugger
trong trang nền / sự kiện để đính kèm vào tab cụ thể mà bạn muốn nghe (hoặc đính kèm vào tất cả các tab nếu có thể, chưa kiểm tra tất cả các tab) , sau đó sử dụng API mạng của giao thức gỡ lỗi.Vấn đề duy nhất với điều này là sẽ có thanh màu vàng thông thường ở đầu khung nhìn của tab, trừ khi người dùng tắt nó đi
chrome://flags
.
Đầu tiên, đính kèm trình gỡ lỗi vào đích:
chrome.debugger.getTargets((targets) => {
let target = /* Find the target. */;
let debuggee = { targetId: target.id };
chrome.debugger.attach(debuggee, "1.2", () => {
// TODO
});
});
Tiếp theo, gửi Network.setRequestInterceptionEnabled
lệnh, lệnh này sẽ cho phép chặn các yêu cầu mạng:
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 bây giờ sẽ bắt đầu gửi Network.requestIntercepted
sự kiện. Thêm người nghe cho họ:
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
}
});
});
Trong người nghe, params.request
sẽ là Request
đối tượng tương ứng .
Gửi phản hồi với Network.continueInterceptedRequest
:
rawResponse
.params.interceptionId
như interceptionId
.Lưu ý rằng tôi chưa thử nghiệm bất kỳ điều nào trong số này.
setRequestInterceptionEnabled
phương pháp dường như không được bao gồm trong v1.2 DevTools giao thức, và tôi không thể tìm thấy một cách để gắn nó với (tip-of-cây) phiên bản mới nhất để thay thế.
chrome.debugger.sendCommand(debuggee, "Network.setRequestInterceptionEnabled", { enabled: true });
không thành công với 'Network.setRequestInterceptionEnabled' không được tìm thấy '
Giống như @Rob w đã nói, tôi đã ghi đè XMLHttpRequest
và đây là kết quả để sửa đổi bất kỳ yêu cầu XHR nào trong bất kỳ trang web nào (hoạt động giống như proxy sửa đổi minh bạch):
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);
};
ví dụ: mã này có thể được sử dụng thành công bởi Tampermonkey để thực hiện bất kỳ sửa đổi nào trên bất kỳ trang web nào :)
response
chứ không phải responseText
, vì vậy tất cả các bạn phải làm là thay đổi Object.defineProperty để sử dụng response
thay vì