HTTP応答本文を変更するChrome拡張機能を作成することは可能ですか?
Chrome拡張APIを調べましたが、これを行うための方法が見つかりませんでした。
HTTP応答本文を変更するChrome拡張機能を作成することは可能ですか?
Chrome拡張APIを調べましたが、これを行うための方法が見つかりませんでした。
webRequest.filterResponseData()。残念ながら、これはFirefoxのみのソリューションです。
                回答:
通常、標準のChrome拡張APIを使用してHTTPリクエストの応答本文を変更することはできません。
この機能は104058でリクエストされています:WebRequest API:拡張機能が応答本文を編集できるようにします。問題にスターを付けて、更新の通知を受け取ります。
あなたは、編集に知られているためレスポンスボディたい場合はXMLHttpRequest、コンテンツのスクリプトによるジェクトコードデフォルト上書きするXMLHttpRequest(フル機能)カスタム実際のイベントをトリガする前に応答を書き換えて1を持つコンストラクタを。XMLHttpRequestオブジェクトがChromeの組み込みオブジェクトに完全に準拠していることを確認してください。準拠していないとXMLHttpRequest、AJAXを多用するサイトが破損します。
それ以外の場合は、chrome.webRequestまたはchrome.declarativeWebRequestAPIを使用してリクエストをdata:-URIにリダイレクトできます。XHRアプローチとは異なり、リクエストの元のコンテンツは取得されません。実際には、リダイレクトは実際の要求が送信される前にしか実行できないため、要求がサーバーに到達することはありません。また、main_frameリクエストをリダイレクトすると、ユーザーdata:にはリクエストされたURLの代わりに-URIが表示されます。
data:text...ですか?
                    私はちょうどそれを行うDevtools拡張機能をリリースしました:)
これはタンパーと呼ばれ、mitmproxyに基づいており、現在のタブからのすべてのリクエストを確認し、それらを変更して、次に更新するときに変更されたバージョンを提供できます。
これはかなり初期のバージョンですが、OSXおよびWindowsと互換性があるはずです。うまくいかない場合はお知らせください。
ここで入手できますhttp://dutzi.github.io/tamper/
これがどのように機能するか
@Xanが以下にコメントしているように、拡張機能はネイティブメッセージングを介してmitmproxyを拡張するPythonスクリプトと通信します。
拡張機能は、を使用してすべてのリクエストを一覧表示しますchrome.devtools.network.onRequestFinished。
リクエストをクリックすると、リクエストオブジェクトのgetContent()メソッドを使用してレスポンスがダウンロードされ、そのレスポンスがPythonスクリプトに送信されてローカルに保存されます。
次に、エディターでファイルを開きます(callOSXまたはsubprocess.PopenWindows用を使用)。
Pythonスクリプトは、mitmproxyを使用して、そのプロキシを介して行われたすべての通信をリッスンします。保存されたファイルの要求を検出すると、代わりに保存されたファイルを提供します。
ChromeのプロキシAPI(具体的にはchrome.proxy.settings.set())を使用して、PACをプロキシ設定として設定しました。そのPACファイルは、すべての通信をPythonスクリプトのプロキシにリダイレクトします。
mitmproxyの最大の利点の1つは、HTTPS通信も変更できることです。だからあなたもそれを持っています:)
はい。これは、ネットワークAPIを介したHTTPインターセプトと変更をサポートするChromeDevToolsプロトコルchrome.debuggerへの拡張アクセスを許可するAPIで可能です。
この解決策は、Chrome Issue487422へのコメントによって提案されました。
現時点で実行可能な代替手段が必要な場合
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。私はこれをまったくテストしていないことに注意してください。
setRequestInterceptionEnabledメソッドはDevToolsプロトコルv1.2に含まれていないようで、代わりに最新の(ツリーのヒント)バージョンにアタッチする方法が見つかりません。
                    chrome.debugger.sendCommand(debuggee, "Network.setRequestInterceptionEnabled", { enabled: true });「Network.setRequestInterceptionEnabled」で失敗したが」が見つかりませんでした
                    @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が任意のサイトで変更を加えるために正常に使用できます:)
responseなく新しいものresponseTextを使用するため、response代わりに使用するようにObject.definePropertyを変更するだけです