क्रोम एक्सटेंशन से वर्तमान पृष्ठ का स्रोत HTML प्राप्त करना


85

मेरा क्रोम एक्सटेंशन है। मुझे वर्तमान पृष्ठ के HTML स्रोत से विश्लेषण करने की आवश्यकता है। मैंने पृष्ठभूमि पृष्ठ और सामग्री स्क्रिप्ट के साथ यहां सभी प्रकार के समाधान पाए, लेकिन किसी ने भी मेरी मदद नहीं की। यहाँ मैं अब तक क्या है
:

{
  "name": "Extension",
  "version": "1.0",
  "description": "Extension",
  "browser_action": {
    "default_icon": "bmarkred.ico",
    "popup": "Test.html"
  },
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "js": ["content.js"]
    }
  ],
  "background": {
    "page": "backgroundPage.html"
  },
  "permissions": [
    "cookies",
    "tabs",
    "http://*/*", 
    "https://*/*"
  ]
}

background.html:

<html>
<head>
<script type="text/javascript">
    try {
        chrome.tabs.getSelected(null, function (tab) {
            chrome.tabs.sendRequest(tab.id, {action: "getSource"}, function(source) {
                alert(source);
            });
        });
    }
    catch (ex) {
        alert(ex);
    }
</script>
</head>
</html>

content.js:

chrome.extension.onRequest.addListener(function(request, sender, callback) {
    if (request.action == "getSource") {
        callback(document.getElementsByTagName('html')[0].innerHTML);
    }
});

अलर्ट हमेशा अपरिभाषित है। भले ही मैं content.js में परिवर्तन करूँ:

callback('hello'); 

अभी भी वही परिणाम है। मैं क्या गलत कर रहा हूं? शायद यह गलत तरीके से चल रहा है। वास्तव में मुझे इसकी आवश्यकता है जब उपयोगकर्ता एक्सटेंशन पॉपअप (और केवल तब) खोलता है, तो मुझे वर्तमान पृष्ठ का HTML चाहिए ताकि मैं इसका विश्लेषण कर सकूं। कोई सुझाव?


एक समस्या यह है कि आपके पृष्ठभूमि पृष्ठ में कोड तुरंत चलाया जाता है (सामग्री स्क्रिप्ट इंजेक्ट होने से पहले)। इससे पहले एक बहुत ही समान / डुप्लिकेट प्रश्न पूछा गया है; एक नया Google Chrome टैब खोलें और स्रोत प्राप्त करें जवाब पर एक नज़र डालें ।
Rob W

आपके उत्तर के लिए धन्यवाद। मैंने आपके संलग्न लिंक में कोड सेगमेंट को कॉपी किया है लेकिन यह अभी भी काम नहीं करता है। समस्या यह है कि मेरा एक्सटेंशन एक पॉपअप है और मुझे केवल HTML प्राप्त करने की आवश्यकता है जब उपयोगकर्ता मेरा एक्सटेंशन खोलता है। उदाहरण के लिए, यदि वर्तमान टैब facebook.com है तो केवल जब मैं अपना एक्सटेंशन खोलूंगा, मैं html स्रोत को अपनी js फ़ाइल (सामग्री स्क्रिप्ट या पृष्ठभूमि पृष्ठ नहीं) को पुनः प्राप्त करूंगा।
श्री टी।

अपने वर्तमान कोड के साथ अपने प्रश्न को अपडेट करें। कोड में टिप्पणियां शामिल हैं जो समस्या को उजागर करती हैं।
रॉब डब्ल्यू

जवाबों:


155

आप जिस स्रोत से स्रोत प्राप्त करना चाहते हैं उस पृष्ठ पर एक स्क्रिप्ट इंजेक्ट करें और उसे वापस पॉपअप पर संदेश भेजें ...।

manifest.json

{
  "name": "Get pages source",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Get pages source from a popup",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": ["tabs", "<all_urls>"]
}

popup.html

<!DOCTYPE html>
<html style=''>
<head>
<script src='popup.js'></script>
</head>
<body style="width:400px;">
<div id='message'>Injecting Script....</div>
</body>
</html>

popup.js

chrome.runtime.onMessage.addListener(function(request, sender) {
  if (request.action == "getSource") {
    message.innerText = request.source;
  }
});

function onWindowLoad() {

  var message = document.querySelector('#message');

  chrome.tabs.executeScript(null, {
    file: "getPagesSource.js"
  }, function() {
    // If you try and inject into an extensions page or the webstore/NTP you'll get an error
    if (chrome.runtime.lastError) {
      message.innerText = 'There was an error injecting script : \n' + chrome.runtime.lastError.message;
    }
  });

}

window.onload = onWindowLoad;

getPagesSource.js

// @author Rob W <http://stackoverflow.com/users/938089/rob-w>
// Demo: var serialized_html = DOMtoString(document);

function DOMtoString(document_root) {
    var html = '',
        node = document_root.firstChild;
    while (node) {
        switch (node.nodeType) {
        case Node.ELEMENT_NODE:
            html += node.outerHTML;
            break;
        case Node.TEXT_NODE:
            html += node.nodeValue;
            break;
        case Node.CDATA_SECTION_NODE:
            html += '<![CDATA[' + node.nodeValue + ']]>';
            break;
        case Node.COMMENT_NODE:
            html += '<!--' + node.nodeValue + '-->';
            break;
        case Node.DOCUMENT_TYPE_NODE:
            // (X)HTML documents are identified by public identifiers
            html += "<!DOCTYPE " + node.name + (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') + (!node.publicId && node.systemId ? ' SYSTEM' : '') + (node.systemId ? ' "' + node.systemId + '"' : '') + '>\n';
            break;
        }
        node = node.nextSibling;
    }
    return html;
}

chrome.runtime.sendMessage({
    action: "getSource",
    source: DOMtoString(document)
});

@Gil Tankus So sorry for my first post, didn't pay enough attention to the comments (again) and ended up just regurgitating what Rob W said. The new post should have what you wanted.
PAEz

Thanks, your answer was really helpful, my problem is that the on onMessage happens asynchronous. in my popup, i have all sorts of other stuff that relay on the source HTML. how can i save the source in a global var and only then continue with the page onload function?
Mr T.

I don't think you can. Your either going to have to put it in the callbacks code or in a function and call that in the callback...if only JS had a goto command aye? ;P
PAEz

19
Why not just something like document.documentElement.outerHTML instead of the DOMtoString function?
djfm

@djfm That would be fine pretty much all of the time. Its just that from what I could tell Rob W's function is more complete...returns the doctype for instance that your solution doesn't, yours is only getting the html part.
PAEz

0

Here is my solution:

chrome.runtime.onMessage.addListener(function(request, sender) {
        if (request.action == "getSource") {
            this.pageSource = request.source;
            var title = this.pageSource.match(/<title[^>]*>([^<]+)<\/title>/)[1];
            alert(title)
        }
    });

    chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
        chrome.tabs.executeScript(
            tabs[0].id,
            { code: 'var s = document.documentElement.outerHTML; chrome.runtime.sendMessage({action: "getSource", source: s});' }
        );
    });
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.