Chrome एक्सटेंशन सामग्री स्क्रिप्ट से popup.html पर डेटा भेजने का तरीका


95

मुझे पता है कि यह कई पोस्टों में पूछा गया है लेकिन ईमानदारी से मैं उन्हें नहीं पाता। मैं जावास्क्रिप्ट, क्रोम एक्सटेंशन और सब कुछ के लिए नया हूं और मेरे पास यह क्लास असाइनमेंट है। तो मुझे एक प्लगइन बनाने की ज़रूरत है जो क्रॉस डोमेन अनुरोधों का उपयोग करके किसी भी पृष्ठ पर डोम वस्तुओं की गणना करेगा। मैं Chrome एक्सटेंशन API का उपयोग करके अब तक इसे प्राप्त करने में सक्षम रहा हूं। अब समस्या यह है कि मुझे contentScript.js फ़ाइल से अपने popup.html पृष्ठ पर डेटा दिखाना होगा। मुझे नहीं पता कि ऐसा कैसे करना है कि मैंने प्रलेखन पढ़ने की कोशिश की है, लेकिन क्रोम में संदेश भेजना मुझे समझ नहीं आ रहा है कि मुझे क्या करना है।

निम्नलिखित अब तक का कोड है।

manifest.json

{
"manifest_version":2,

"name":"Dom Reader",
"description":"Counts Dom Objects",
"version":"1.0",

"page_action": {
    "default_icon":"icon.png",
    "default_title":"Dom Reader",
    "default_popup":"popup.html"
},

"background":{
    "scripts":["eventPage.js"],
    "persistent":false
},

"content_scripts":[
    {
        "matches":["http://pluralsight.com/training/Courses/*", "http://pluralsight.com/training/Authors/Details/*",                                          "https://www.youtube.com/user/*", "https://sites.google.com/site/*", "http://127.0.0.1:3667/popup.html"],
        "js":["domReader_cs.js","jquery-1.10.2.js"]
        //"css":["pluralsight_cs.css"]
    }
],

"permissions":[
    "tabs",
    "http://pluralsight.com/*",
    "http://youtube.com/*",
    "https://sites.google.com/*",
    "http://127.0.0.1:3667/*"
]

popup.html

<!doctype html>
<html>

    <title> Dom Reader </title>    
    <script src="jquery-1.10.2.js" type="text/javascript"></script>
    <script src="popup.js" type="text/javascript"></script>

<body>
    <H1> Dom Reader </H1>
    <input type="submit" id="readDom" value="Read DOM Objects" />

   <div id="domInfo">

    </div>
</body>
</html>

eventPage.js

var value1,value2,value3;

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action == "show") {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        chrome.pageAction.show(tabs[0].id);
    });
}

value1 = request.tElements;
});

popup.js

$(function (){
$('#readDom').click(function(){
chrome.tabs.query({active: true, currentWindow: true}, function (tabs){
    chrome.tabs.sendMessage(tabs[0].id, {action: "readDom"});

 });
});
});

contentScript

var totalElements;
var inputFields;
var buttonElement;

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
if(request.action == "readDom"){

    totalElements = $("*").length;
    inputFields = $("input").length;
    buttonElement = $("button").length;


}
})

chrome.runtime.sendMessage({ 
action: "show", 
tElements: totalElements, 
Ifields: inputFields, 
bElements: buttonElement 

});

किसी भी मदद की सराहना की जाएगी और कृपया किसी भी अच्छाई से बचें जो मैंने किया :)

जवाबों:


171

यद्यपि आप निश्चित रूप से सही दिशा में हैं (और वास्तव में बहुत करीब हैं), आपके कोड में कई (imo) बुरी प्रथाएं हैं (उदाहरण के लिए, इस तरह के एक तुच्छ कार्य के लिए पूरी लाइब्रेरी (jquery को इंजेक्ट करना), अनावश्यक अनुमतियों की घोषणा करना, सुपरफ्लस बनाना एपीआई तरीकों आदि के लिए कॉल)।
मैंने स्वयं आपके कोड का परीक्षण नहीं किया था, लेकिन एक त्वरित अवलोकन से मेरा मानना ​​है कि निम्नलिखित को सही करने से काम करने वाला समाधान निकल सकता है (हालांकि इष्टतम के बहुत करीब नहीं):

  1. में manifest.json : बदलें सामग्री स्क्रिप्ट के क्रम, पहले jQuery डाल। प्रासंगिक डॉक्स के अनुसार :

    "js" [...] मिलान पृष्ठों में इंजेक्शन की जाने वाली जावास्क्रिप्ट फ़ाइलों की सूची। वे इस सरणी में दिखाई देने वाले क्रम में अंतःक्षिप्त हैं ।

    (जोर मेरा)

  2. में contentscript.js : ले जाएँ chrome.runtime.sendMessage ({...}) ब्लॉक के अंदरonMessage श्रोता कॉलबैक।


उस ने कहा, यहाँ मेरा प्रस्तावित दृष्टिकोण है:

बहाव को काबू करें:

  1. एक सामग्री स्क्रिप्ट को प्रत्येक पृष्ठ में कुछ मानदंडों के साथ इंजेक्ट किया जाता है।
  2. एक बार इंजेक्शन लगाने के बाद, सामग्री स्क्रिप्ट ईवेंट पृष्ठ (उर्फ गैर-स्थायी पृष्ठभूमि पृष्ठ) पर एक संदेश भेजती है और ईवेंट पृष्ठ टैब पर एक पृष्ठ-कार्रवाई संलग्न करता है।
  3. जैसे ही पेज-एक्शन पॉपअप लोड होता है, यह सामग्री स्क्रिप्ट को एक संदेश भेजता है, इसके लिए आवश्यक जानकारी मांगता है।
  4. सामग्री स्क्रिप्ट अनुरोध को संसाधित करती है, और प्रतिक्रिया देती है ताकि पृष्ठ-क्रिया पॉपअप जानकारी प्रदर्शित कर सके।

निर्देशिका संरचना:

          root-directory/
           |_____img
                 |_____icon19.png
                 |_____icon38.png
           |_____manifest.json
           |_____background.js
           |_____content.js
           |_____popup.js
           |_____popup.html

manifest.json:

{
  "manifest_version": 2,
  "name": "Test Extension",
  "version": "0.0",
  "offline_enabled": true,

  "background": {
    "persistent": false,
    "scripts": ["background.js"]
  },

  "content_scripts": [{
    "matches": ["*://*.stackoverflow.com/*"],
    "js": ["content.js"],
    "run_at": "document_idle",
    "all_frames": false
  }],

  "page_action": {
    "default_title": "Test Extension",
    //"default_icon": {
    //  "19": "img/icon19.png",
    //  "38": "img/icon38.png"
    //},
    "default_popup": "popup.html"
  }

  // No special permissions required...
  //"permissions": []
}

background.js:

chrome.runtime.onMessage.addListener((msg, sender) => {
  // First, validate the message's structure.
  if ((msg.from === 'content') && (msg.subject === 'showPageAction')) {
    // Enable the page-action for the requesting tab.
    chrome.pageAction.show(sender.tab.id);
  }
});

content.js:

// Inform the background page that 
// this tab should have a page-action.
chrome.runtime.sendMessage({
  from: 'content',
  subject: 'showPageAction',
});

// Listen for messages from the popup.
chrome.runtime.onMessage.addListener((msg, sender, response) => {
  // First, validate the message's structure.
  if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) {
    // Collect the necessary data. 
    // (For your specific requirements `document.querySelectorAll(...)`
    //  should be equivalent to jquery's `$(...)`.)
    var domInfo = {
      total: document.querySelectorAll('*').length,
      inputs: document.querySelectorAll('input').length,
      buttons: document.querySelectorAll('button').length,
    };

    // Directly respond to the sender (popup), 
    // through the specified callback.
    response(domInfo);
  }
});

popup.js:

// Update the relevant fields with the new data.
const setDOMInfo = info => {
  document.getElementById('total').textContent = info.total;
  document.getElementById('inputs').textContent = info.inputs;
  document.getElementById('buttons').textContent = info.buttons;
};

// Once the DOM is ready...
window.addEventListener('DOMContentLoaded', () => {
  // ...query for the active tab...
  chrome.tabs.query({
    active: true,
    currentWindow: true
  }, tabs => {
    // ...and send a request for the DOM info...
    chrome.tabs.sendMessage(
        tabs[0].id,
        {from: 'popup', subject: 'DOMInfo'},
        // ...also specifying a callback to be called 
        //    from the receiving end (content script).
        setDOMInfo);
  });
});

popup.html:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="popup.js"></script>
  </head>
  <body>
    <h3 style="font-weight:bold; text-align:center;">DOM Info</h3>
    <table border="1" cellpadding="3" style="border-collapse:collapse;">
      <tr>
        <td nowrap>Total number of elements:</td>
        <td align="right"><span id="total">N/A</span></td>
      </tr>
      <tr>
        <td nowrap>Number of input elements:</td>
        <td align="right"><span id="inputs">N/A</span></td>
      </tr>
      <tr>
        <td nowrap>Number of button elements:</td>
        <td align="right"><span id="buttons">N/A</span></td>
      </tr>
    </table>
  </body>
</html>

वाह ! धन्यवाद भाई, आपके दृष्टिकोण की जाँच अब मुझे लगता है कि मैंने अपने कोड के साथ कितनी समस्याएं पैदा की हैं। बहुत बहुत धन्यवाद यह एक आकर्षण की तरह काम करता है। :)
सुमिर बलूच

हैलो, क्षमा करें, मैं कुछ समय के लिए नहीं गया, बस आपकी टिप्पणी पर जाँच की गई। मैं किसी भी उत्तर को स्वीकार नहीं कर सकता। यह कहता है कि आपको ऐसा करने के लिए 15 प्रतिष्ठा बिंदुओं की आवश्यकता है।
सुमिर बलूच

क्या आप एक समान समस्या को हल करने में मेरी मदद करेंगे? <a href=" stackoverflow.com/questions/34467627/…> इस पर मेरा वर्तमान शॉट इस उत्तर से आपका कोड बहुत अधिक है। लेकिन मुझे अभी भी यह काम करने के लिए नहीं मिला है और इस मामले पर कोई अच्छी मदद नहीं मिल रही है।
wuno

तुम क्यों इस्तेमाल किया chrome.tabs.sendMessagepopupjs में और chrome.runtime.onMessage.addListenerक्यों content.js में .tabspopupjs के लिए और .runtimecontent.js में
हबीब Kazemi

2
@ किमी: क्योंकि यह है कि आप कैसे संदेश भेजने और प्राप्त करते हैं। यह डॉक्स में है
गल्पक

7

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

contentScript.js में:

chrome.runtime.sendMessage({
  total_elements: totalElements // or whatever you want to send
});

in EventPage.js (आपकी पृष्ठभूमि पृष्ठ):

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse){
       localStorage["total_elements"] = request.total_elements;
    }
);

फिर आप उस वैरिएबल को popSt.js में localStorage ["total_elements"] के साथ एक्सेस कर सकते हैं।

हो सकता है कि आप आधुनिक ब्राउज़र में सामग्री स्क्रिप्ट से सीधे लोकलस्टोरेज का उपयोग कर सकते हैं। तब आपको अपने पृष्ठ के पृष्ठ के माध्यम से डेटा पास करने की आवश्यकता नहीं है।

LocalStorage के बारे में अच्छा पढ़ने: http://diveintohtml5.info/storage.html


1
कृपया, हटाए गए chrome.extension.onRequest / sendRequest (जो btw निष्पादित करने से पहले एक गैर-निरंतर पृष्ठभूमि पृष्ठ को लोड नहीं करते हैं) के उपयोग को बढ़ावा न दें । इसके बजाय chrome.runtime का उपयोग करें ।
गल्पक

1
@ExpertSystem कृपया, यदि आप ऐसी पुरानी जानकारी देखते हैं, तो सुझाव दें / संपादित करें।
Xan

3
@ Xan: तो, आप [Google-Chrome-Extension] में उत्तराधिकारी हैं :) मुझे लोगों के पोस्ट संपादित करना पसंद नहीं है (मुझे यह बहुत पेचीदा लगता है)। इसके अलावा, बहुत सारे पुराने ट्यूटोरियल और उदाहरण (कम से कम वापस) के बाद, मुझे यह स्पष्ट करना बेहतर लगा कि क्यों इसका उपयोग करना बुरा है .extension.xxx, बजाय इसके कि केवल सही तरीके से दिखाया जाए (जो कुछ लोग "के रूप में सोच सकते हैं" समान रूप से ठीक विकल्प ")। मुझे लगता है कि यह शैली की बात है। अच्छा काम करते रहें !
गल्पक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.