क्रोम एक्सटेंशन - डोम सामग्री प्राप्त करें


116

मैं अपने पॉपअप से एक्टिवटैब डोम कंटेंट को एक्सेस करने की कोशिश कर रहा हूं। यहाँ मेरी अभिव्यक्ति है:

{
  "manifest_version": 2,

  "name": "Test",
  "description": "Test script",
  "version": "0.1",

  "permissions": [
    "activeTab",
    "https://api.domain.com/"
  ],

  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",

  "browser_action": {
    "default_icon": "icon.png",
    "default_title": "Chrome Extension test",
    "default_popup": "index.html"
  }
}

मैं वास्तव में भ्रमित हूं कि क्या पृष्ठभूमि स्क्रिप्ट (दृढ़ता के साथ घटना पृष्ठ: गलत) या content_scripts जाने का रास्ता है। मैंने सभी दस्तावेज और अन्य SO पोस्ट पढ़े हैं और यह अभी भी मेरे लिए कोई मायने नहीं रखता है।

क्या कोई समझा सकता है कि मैं एक का उपयोग क्यों कर सकता हूं।

यहाँ पृष्ठभूमि है। जेएस कि मैं कोशिश कर रहा हूँ:

chrome.extension.onMessage.addListener(
  function(request, sender, sendResponse) {
    // LOG THE CONTENTS HERE
    console.log(request.content);
  }
);

और मैं इसे पॉपअप कंसोल से निष्पादित कर रहा हूं:

chrome.tabs.getSelected(null, function(tab) {
  chrome.tabs.sendMessage(tab.id, { }, function(response) {
    console.log(response);
  });
});

मैं ला रहा हूँ:

Port: Could not establish connection. Receiving end does not exist. 

अपडेट करें:

{
  "manifest_version": 2,

  "name": "test",
  "description": "test",
  "version": "0.1",

  "permissions": [
    "tabs",
    "activeTab",
    "https://api.domain.com/"
  ],

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],

  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",

  "browser_action": {
    "default_icon": "icon.png",
    "default_title": "Test",
    "default_popup": "index.html"
  }
}

content.js

chrome.extension.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.text && (request.text == "getDOM")) {
      sendResponse({ dom: document.body.innerHTML });
    }
  }
);

popup.html

chrome.tabs.getSelected(null, function(tab) {
  chrome.tabs.sendMessage(tab.id, { action: "getDOM" }, function(response) {
    console.log(response);
  });
});

जब मैं इसे चलाता हूं, तब भी मुझे वही त्रुटि मिलती है:

undefined
Port: Could not establish connection. Receiving end does not exist. lastError:30
undefined

जवाबों:


184

"पृष्ठभूमि पृष्ठ", "पॉपअप", "सामग्री स्क्रिप्ट" शब्द अभी भी आपको भ्रमित कर रहे हैं; मैं Google Chrome एक्सटेंशन डॉक्यूमेंटेशन पर अधिक गहराई से देखने का सुझाव देता हूं ।

आपके प्रश्न के बारे में यदि सामग्री स्क्रिप्ट या पृष्ठभूमि पृष्ठ जाने का तरीका है:

सामग्री स्क्रिप्ट : निश्चित रूप से
सामग्री स्क्रिप्ट एक विस्तार का एकमात्र घटक है जिसकी वेब-पेज की DOM तक पहुँच है।

बैकग्राउंड पेज / पॉपअप : हो सकता है (शायद दो में से अधिकतम 1)
आपको आगे की प्रक्रिया के लिए बैकग्राउंड पेज या पॉपअप में कंटेंट स्क्रिप्ट को डोम कंटेंट पास करना होगा।


मुझे दोहराने दो कि मैं दृढ़ता से उपलब्ध दस्तावेज के अधिक सावधान अध्ययन की सलाह देता हूं!
उस ने कहा, यहाँ एक नमूना विस्तार है जो StackOverflow पृष्ठों पर DOM सामग्री को पुनः प्राप्त करता है और इसे पृष्ठभूमि पृष्ठ पर भेजता है, जो इसे कंसोल में प्रिंट करता है:

background.js:

// Regex-pattern to check URLs against. 
// It matches URLs like: http[s]://[...]stackoverflow.com[...]
var urlRegex = /^https?:\/\/(?:[^./?#]+\.)?stackoverflow\.com/;

// A function to use as callback
function doStuffWithDom(domContent) {
    console.log('I received the following DOM content:\n' + domContent);
}

// When the browser-action button is clicked...
chrome.browserAction.onClicked.addListener(function (tab) {
    // ...check the URL of the active tab against our pattern and...
    if (urlRegex.test(tab.url)) {
        // ...if it matches, send a message specifying a callback too
        chrome.tabs.sendMessage(tab.id, {text: 'report_back'}, doStuffWithDom);
    }
});

content.js:

// Listen for messages
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
    // If the received message has the expected format...
    if (msg.text === 'report_back') {
        // Call the specified callback, passing
        // the web-page's DOM content as argument
        sendResponse(document.all[0].outerHTML);
    }
});

manifest.json:

{
  "manifest_version": 2,
  "name": "Test Extension",
  "version": "0.0",
  ...

  "background": {
    "persistent": false,
    "scripts": ["background.js"]
  },
  "content_scripts": [{
    "matches": ["*://*.stackoverflow.com/*"],
    "js": ["content.js"]
  }],
  "browser_action": {
    "default_title": "Test Extension"
  },

  "permissions": ["activeTab"]
}

6
@ सॉल्विंगपश्चिम: chrome.runtime.sendMessageबैकग्राउंडपेज और पॉपअप को संदेश भेजता है। chrome.tabs.sendMessageContentScripts को संदेश भेजता है।
गल्पक

22
डाउनवोट किया गया क्योंकि यह उत्तर यह स्पष्ट नहीं करता है कि वर्तमान टैब से ACTUAL DOM कैसे प्राप्त करें।
जॉन पॉल बारबागलो

2
@JohnPaulBarbagallo: सवाल डोम कंटेंट प्राप्त करने के बारे में था, वास्तविक डोम तक पहुँचने / हेरफेर करने के बारे में नहीं। मुझे लगता है कि मेरा उत्तर ऐसा करता है (और अन्य लोग भी ऐसा ही सोचते हैं)। यदि आपके पास एक बेहतर समाधान है, तो इसे उत्तर के रूप में पोस्ट करें। यदि आपके पास एक अलग आवश्यकता है, तो इसे एक नए प्रश्न के रूप में पोस्ट करें। किसी भी मामले में, प्रतिक्रिया के लिए thx :)
gkalpak

2
@ ज़ोल्टर: यह बैकग्राउंड-पेज के कंसोल में छपा है।
गल्पक

2
मेरे पास इस उत्तर की कॉपी / पेस्टर है लेकिन सामग्री कंसोल के रूप में कोई भी कंसोल नहीं मिल सकता है। कृपया मदद करें!
क्लेमेंटवेल्टर

72

DOM को प्राप्त करने या संशोधित करने के लिए आपको संदेश का उपयोग करने की आवश्यकता नहीं है। मैं chrome.tabs.executeScriptइसके बजाय इस्तेमाल किया। मेरे उदाहरण में मैं केवल सक्रिय टैब अनुमति का उपयोग कर रहा हूं, इसलिए स्क्रिप्ट को केवल सक्रिय टैब पर निष्पादित किया जाता है।

प्रकट का भाग। json

"browser_action": {
    "default_title": "Test",
    "default_popup": "index.html"
},
"permissions": [
    "activeTab",
    "<all_urls>"
]

index.html

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <button id="test">TEST!</button>
    <script src="test.js"></script>
  </body>
</html>

test.js

document.getElementById("test").addEventListener('click', () => {
    console.log("Popup DOM fully loaded and parsed");

    function modifyDOM() {
        //You can play with your DOM here or check URL against your regex
        console.log('Tab script:');
        console.log(document.body);
        return document.body.innerHTML;
    }

    //We have permission to access the activeTab, so we can call chrome.tabs.executeScript:
    chrome.tabs.executeScript({
        code: '(' + modifyDOM + ')();' //argument here is a string but function.toString() returns function's code
    }, (results) => {
        //Here we have just the innerHTML and not DOM structure
        console.log('Popup script:')
        console.log(results[0]);
    });
});

1
अच्छी तरह से काम! धन्यवाद। मुझे पता नहीं क्यों, लेकिन मैं मेरे लिए स्वीकृत समाधान काम नहीं कर सका।
गुडफेलो

आपका यह कथन कि आप केवल activeTabअनुमति का उपयोग कर रहे हैं , गलत है। आप स्पष्ट रूप <all_urls>से इसके अतिरिक्त प्राप्त कर रहे हैं activeTab
Makyen

1
test.js एक स्क्रिप्ट है जिसे आपने अपने पेज के HTML में शामिल किया है, इसलिए मुझे यकीन नहीं है कि आपको किसी भी अनुमति की आवश्यकता है ।
स्कॉट बेकर

11

उन लोगों के लिए जिन्होंने गोलक उत्तर की कोशिश की और यह काम नहीं किया,

इस बात से अवगत रहें कि क्रोम एक आवश्यक पृष्ठ पर सामग्री स्क्रिप्ट तभी जोड़ेगा जब आपका एक्सटेंशन क्रोम लॉन्च के दौरान सक्षम हो और इन परिवर्तनों को करने के बाद एक अच्छा विचार पुनः आरंभ करें ब्राउज़र


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