Chrome एक्सटेंशन से HTTP प्रतिक्रियाओं को संशोधित करें


83

क्या Chrome एक्सटेंशन बनाना संभव है जो HTTP प्रतिसाद निकायों को संशोधित करता है?

मैंने Chrome एक्सटेंशन API में देखा है , लेकिन मुझे ऐसा करने के लिए कुछ भी नहीं मिला है।


1
सामान्य तौर पर, नहीं। Https://code.google.com/p/chromium/issues/detail?id=104058 देखें । उपयोग मामलों के सबसेट के लिए, हाँ। क्या आप स्पष्ट कर सकते हैं कि आप प्रतिक्रिया निकायों को क्यों संपादित करना चाहते हैं?
रॉब डब्ल्यू

ठीक है धन्यवाद। कृपया इसे उत्तर के रूप में लिखें और मैं इसे स्वीकार करूंगा।
कैप्टन ड्रैगन

यदि आप अन्य ब्राउज़रों को स्वीकार करते हैं, तो फ़ायरफ़ॉक्स समर्थन करता है webRequest.filterResponseData()। दुर्भाग्य से यह एक फ़ायरफ़ॉक्स-मात्र समाधान है।
फ्रैंकलिन यू

जवाबों:


49

सामान्य तौर पर, आप मानक क्रोम एक्सटेंशन API का उपयोग करके HTTP अनुरोध के प्रतिक्रिया निकाय को नहीं बदल सकते

इस सुविधा का अनुरोध 104058: WebRequest API: एक्सटेंशन को प्रतिक्रिया बॉडी को संपादित करने के लिए किया जाता है । अद्यतनों की सूचना प्राप्त करने के लिए समस्या को स्टार दें।

यदि आप किसी ज्ञात के लिए प्रतिसाद निकाय को संपादित करना चाहते हैं XMLHttpRequest, तो कस्टम स्क्रिप्ट केXMLHttpRequest साथ डिफ़ॉल्ट कंस्ट्रक्टर को ओवरराइड करने के लिए एक कंटेंट स्क्रिप्ट के माध्यम से कोड को इंजेक्ट करें (पूर्ण विशेषताओं वाला) जो वास्तविक घटना को ट्रिगर करने से पहले प्रतिक्रिया को फिर से लिखता है। सुनिश्चित करें कि आपका XMLHttpRequest ऑब्जेक्ट पूरी तरह से क्रोम की अंतर्निहित XMLHttpRequestवस्तु के साथ संगत है , या AJAX- भारी साइटें टूट जाएंगी।

अन्य मामलों में, आप chrome.webRequestया chrome.declarativeWebRequestAPI का उपयोग करके data:aURI के अनुरोध को पुनर्निर्देशित कर सकते हैं । XHR-दृष्टिकोण के विपरीत, आपको अनुरोध की मूल सामग्री नहीं मिलेगी। वास्तव में, अनुरोध सर्वर से कभी नहीं टकराएगा क्योंकि पुनर्निर्देशन केवल वास्तविक अनुरोध भेजे जाने से पहले किया जा सकता है। और यदि आप किसी main_frameअनुरोध को पुनर्निर्देशित करते हैं, तो उपयोगकर्ता data:अनुरोधित URL के बजाय -URI को देखेगा।


1
मुझे नहीं लगता कि डेटा: -यूआरआई विचार काम करता है। मैंने बस ऐसा करने की कोशिश की और ऐसा लगता है कि कॉर्स इसे ब्लॉक करता है। मूल अनुरोध करने वाला पृष्ठ यह कहते हुए समाप्त होता है: "अनुरोध को 'डेटा: टेक्स्ट / जोंस; {...}' पर पुनर्निर्देशित किया गया था, जिसे क्रॉस-ऑरिजिनल अनुरोधों के लिए अस्वीकृत कर दिया जाता है जिन्हें प्रीफ़्लाइट की आवश्यकता होती है।"
जो

@ जोए क्रोमियम में प्रजनन नहीं कर सकते हैं 39.0.2171.96
रोब डब्ल्यू

1
@RobW, URL को बदलने से रोकने के लिए कुछ हैक या समाधान क्या हैं data:text...?
पचेरियर

1
@ स्पेसर वास्तव में एक संतोषजनक समाधान नहीं है। मेरे जवाब में मैंने पहले ही सामग्री को बदलने के लिए एक सामग्री स्क्रिप्ट का उपयोग करने के विकल्प का उल्लेख किया था, लेकिन इसके अलावा आप URL को बदले बिना प्रतिक्रिया को "संशोधित" नहीं कर सकते।
रोब डब्ल्यू

1
मैंने इस समाधान की कोशिश की। ध्यान दें कि आपको XMLHttpRequest के अलावा ओवरराइड लाने की आवश्यकता हो सकती है। सीमा यह है कि ब्राउज़र के js / images / css के अनुरोधों को बाधित नहीं किया गया है।
user861746

27

मैंने अभी-अभी एक Devtools एक्सटेंशन जारी किया है जो :)

इसे छेड़छाड़ कहा जाता है, यह मितप्रोक्सी पर आधारित है और यह आपको वर्तमान टैब द्वारा किए गए सभी अनुरोधों को देखने, उन्हें संशोधित करने और अगली बार जब आप ताज़ा करते हैं तो संशोधित संस्करण की सेवा करने की अनुमति देता है।

यह एक बहुत ही प्रारंभिक संस्करण है, लेकिन यह ओएस एक्स और विंडोज के साथ संगत होना चाहिए। मुझे पता है अगर यह आपके लिए काम नहीं करता है।

आप इसे यहाँ पा सकते हैं http://dutzi.github.io/tamper/

यह कैसे काम करता है

जैसा कि @Xan ने नीचे टिप्पणी की है, विस्तार एक मूल स्क्रिप्ट के साथ मूल संदेश के माध्यम से संचार करता है जो माइटप्रॉक्सी को विस्तारित करता है

एक्सटेंशन सभी अनुरोधों का उपयोग करके सूचीबद्ध करता है chrome.devtools.network.onRequestFinished

जब आप अनुरोधों पर क्लिक करते हैं तो यह अनुरोध ऑब्जेक्ट की getContent()विधि का उपयोग करके अपनी प्रतिक्रिया डाउनलोड करता है , और फिर उस प्रतिक्रिया को अजगर स्क्रिप्ट पर भेजता है जो इसे स्थानीय रूप से बचाता है।

यह तब एक संपादक में फ़ाइल खोलता है ( callOSX के लिए या subprocess.Popenविंडोज़ के लिए)।

पाइथन स्क्रिप्ट उस प्रॉक्सी के माध्यम से किए गए सभी संचारों को सुनने के लिए मितप्रोक्सी का उपयोग करती है, अगर यह एक फ़ाइल के लिए एक अनुरोध का पता लगाता है जो सहेजा गया था यह उस फ़ाइल की सेवा करता है जो इसके बजाय सहेजी गई थी।

मैंने chrome.proxy.settings.set()पीएसी को प्रॉक्सी सेटिंग के रूप में सेट करने के लिए क्रोम के प्रॉक्सी एपीआई (विशेष रूप से ) का उपयोग किया । उस पीएसी फ़ाइल को अजगर स्क्रिप्ट के प्रॉक्सी के लिए सभी संचार पुनर्निर्देशित करता है।

मितप्रोक्सी के बारे में एक सबसे बड़ी बात यह है कि यह HTTP संचार को भी संशोधित कर सकता है। तो आपके पास भी है :)


दिलचस्प समाधान, हालांकि इसके लिए एक मूल निवासी होस्ट मॉड्यूल की आवश्यकता होती है।
Xan

5
यह मदद करेगा, वैसे, यदि आप बेहतर तरीके से यहां इस्तेमाल की जाने वाली तकनीक की व्याख्या करते हैं।
Xan

10
दिलचस्प Devtools एक्सटेंशन! हालाँकि ऐसा लगता है कि कोई केवल प्रतिक्रिया शीर्षकों को संशोधित कर सकता है और छेड़छाड़ वाले प्रतिक्रिया निकाय को नहीं ।
माइकल ट्रू

3
स्थापना के साथ समस्या।
दिमित्री प्लेशकोव

1
क्या हम इसके साथ प्रतिक्रिया निकाय को संशोधित कर सकते हैं?
किरण

17

हाँ। यह chrome.debuggerएपीआई के साथ संभव है, जो क्रोम देवटूल प्रोटोकॉल तक पहुंच को बढ़ाता है , जो अपने नेटवर्क एपीआई के माध्यम से HTTP अवरोधन और संशोधन का समर्थन करता है

यह समाधान Chrome समस्या 487422 पर एक टिप्पणी द्वारा सुझाया गया था :

किसी ऐसे विकल्प की इच्छा रखने वाले व्यक्ति के लिए जो इस समय संभव है, आप chrome.debuggerजिस टैब को सुनना चाहते हैं , उसे एक पृष्ठभूमि / घटना पृष्ठ में उपयोग कर सकते हैं (या यदि संभव हो तो सभी टैब से संलग्न कर सकते हैं, व्यक्तिगत रूप से सभी टैब का परीक्षण नहीं किया है) , तो डिबगिंग प्रोटोकॉल के नेटवर्क एपीआई का उपयोग करें।

इसके साथ एकमात्र समस्या यह है कि टैब के व्यूपोर्ट के शीर्ष पर सामान्य पीली पट्टी होगी, जब तक कि उपयोगकर्ता इसे बंद नहीं करता 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:

  • एक बेस 64 अपने वांछित HTTP कच्चे प्रतिक्रिया (की एन्कोडिंग दर्रा HTTP स्थिति लाइन, हेडर, आदि! सहित के रूप में) rawResponse
  • पास के params.interceptionIdरूप में interceptionId

ध्यान दें कि मैंने इनमें से किसी का भी परीक्षण नहीं किया है।


बहुत ही आशाजनक लगता है, हालाँकि मैं इसे अभी (Chrome 60) आज़मा रहा हूँ और या तो मुझे कुछ याद आ रहा है या यह अभी भी संभव नहीं है; setRequestInterceptionEnabledविधि DevTools प्रोटोकॉल v1.2 में शामिल नहीं किया जा रहा है, और मैं नवीनतम (टिप-ऑफ-वृक्ष) के बजाय संस्करण के साथ अटैच करने के लिए एक तरह से नहीं मिल रहा।
ऐयोरोस

1
मैंने इस समाधान की कोशिश की और इसने कुछ हद तक काम किया। यदि आप अनुरोध को संशोधित करना चाहते हैं, तो यह समाधान अच्छा है। यदि आप सर्वर द्वारा दी गई प्रतिक्रिया के आधार पर प्रतिक्रिया को संशोधित करना चाहते हैं, तो कोई रास्ता नहीं है। उस बिंदु पर कोई प्रतिक्रिया नहीं है। कोज के रूप में आप लेखक ने कहा कि कच्चे माल को अधिलेखित कर सकते हैं।
user861746

1
chrome.debugger.sendCommand(debuggee, "Network.setRequestInterceptionEnabled", { enabled: true });'Network.setRequestInterceptionEnabled' नहीं मिला 'के साथ विफल रहता है
Pacerier

1
@ MultiplyByZer0, Ok काम करने में कामयाब रहा। i.stack.imgur.com/n0Gff.png हालाँकि, '
पचेरियर

@ स्पेसर आप सही हैं कि यह समाधान आदर्श नहीं है, लेकिन मैं किसी भी बेहतर के बारे में नहीं जानता। इसके अलावा, जैसा कि आपने देखा है, यह उत्तर अधूरा है और अद्यतन करने की आवश्यकता है। मैं जल्द ही, उम्मीद है कि करूँगा
MultiplyByZer0

13

जैसे @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);
};

उदाहरण के लिए इस कोड को किसी भी साइट पर कोई भी संशोधन करने के लिए टैम्परमोंकी द्वारा सफलतापूर्वक उपयोग किया जा सकता है :)


1
मैंने आपको कोड का उपयोग किया है, और यह कंसोल पर पकड़ा गया लॉग किया है, लेकिन इसने उस प्रतिक्रिया को नहीं बदला जो मेरे आवेदन को मिला (कोणीय)।
एंड्रे रोजगेरी कैम्पोस

2
@ AndréRoggeriCampos मैं एक ही चीज़ में भाग गया। कोणीय नए का उपयोग करता है responseके बजाय responseText, तुम सब करने की ज़रूरत है ताकि Object.defineProperty बदल उपयोग करने के लिए है responseबजाय
जोनाथन Gawrych

आपका बहुत बहुत धन्यवाद ! यह मेरे क्रोम एक्सटेंशन पर काम करता है!
लांसर .Yan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.