कॉन्टेंट स्क्रिप्ट

कॉन्टेंट स्क्रिप्ट ऐसी फ़ाइलें होती हैं जो वेब पेजों के हिसाब से काम करती हैं. स्टैंडर्ड डॉक्यूमेंट ऑब्जेक्ट मॉडल (DOM) का इस्तेमाल करके, वे उन वेब पेजों की जानकारी पढ़ सकते हैं जिन पर ब्राउज़र विज़िट करता है, उनमें बदलाव कर सकते हैं, और अपने पैरंट एक्सटेंशन में जानकारी भेज सकते हैं.

कॉन्टेंट के लिए स्क्रिप्ट की सुविधाओं को समझना

कॉन्टेंट स्क्रिप्ट, एक्सटेंशन फ़ाइलों को ऐक्सेस कर सकती हैं. इसके लिए, उन्हें वेब से ऐक्सेस किए जा सकने वाले रिसॉर्स के तौर पर एलान करना होगा. वे नीचे दिए गए एक्सटेंशन एपीआई को सीधे ऐक्सेस कर सकते हैं:

कॉन्टेंट स्क्रिप्ट, अन्य एपीआई को सीधे ऐक्सेस नहीं कर सकतीं. हालांकि, वे आपके एक्सटेंशन के दूसरे हिस्सों के साथ मैसेज का लेन-देन करके, उन्हें सीधे ऐक्सेस कर सकते हैं.

अलग-अलग जगहों पर काम करें

कॉन्टेंट स्क्रिप्ट एक अलग दुनिया में रहती हैं. इससे कॉन्टेंट स्क्रिप्ट, पेज या दूसरे एक्सटेंशन की कॉन्टेंट स्क्रिप्ट से टकराव किए बिना, JavaScript एनवायरमेंट में बदलाव कर सकती है.

नीचे दिए गए उदाहरण से मिलते-जुलते कोड वाले वेब पेज पर एक्सटेंशन चल सकता है.

webPage.html

<html>
  <button id="mybutton">click me</button>
  <script>
    var greeting = "hello, ";
    var button = document.getElementById("mybutton");
    button.person_name = "Bob";
    button.addEventListener(
        "click", () => alert(greeting + button.person_name + "."), false);
  </script>
</html>

वह एक्सटेंशन स्क्रिप्ट इंजेक्ट करें सेक्शन में बताई गई तकनीक में से किसी एक का इस्तेमाल करके, नीचे दिया गया कॉन्टेंट स्क्रिप्ट इंजेक्ट कर सकता है.

content-script.js

var greeting = "hola, ";
var button = document.getElementById("mybutton");
button.person_name = "Roberto";
button.addEventListener(
    "click", () => alert(greeting + button.person_name + "."), false);

इस बदलाव के बाद, बटन पर क्लिक किए जाने पर दोनों सूचनाएं क्रम में दिखेंगी.

स्क्रिप्ट इंजेक्ट करें

कॉन्टेंट स्क्रिप्ट के बारे में स्टैटिक तरीके से, डाइनैमिक तौर पर एलान किया गया या प्रोग्राम के हिसाब से इंजेक्ट किया जा सकता है.

स्टैटिक जानकारी के साथ इंजेक्ट करें

उन स्क्रिप्ट के लिए Manifest.json में स्टैटिक कॉन्टेंट स्क्रिप्ट की जानकारी का इस्तेमाल करें जो लोकप्रिय पेजों के सेट पर अपने-आप चलनी चाहिए.

स्टैटिक तरीके से एलान की गई स्क्रिप्ट, मेनिफ़ेस्ट में "content_scripts" कुंजी के तहत रजिस्टर होती हैं. उनमें JavaScript फ़ाइलें, सीएसएस फ़ाइलें या दोनों शामिल हो सकते हैं. अपने-आप चलने वाली सभी कॉन्टेंट स्क्रिप्ट में, मिलते-जुलते पैटर्न तय होने चाहिए.

manifest.json

{
 "name": "My extension",
 ...
 "content_scripts": [
   {
     "matches": ["https://*.nytimes.com/*"],
     "css": ["my-styles.css"],
     "js": ["content-script.js"]
   }
 ],
 ...
}

नाम टाइप ब्यौरा
matches स्ट्रिंग का कलेक्शन ज़रूरी है. इससे पता चलता है कि यह कॉन्टेंट स्क्रिप्ट किन पेजों पर इंजेक्ट की जाएगी. इन स्ट्रिंग के सिंटैक्स के बारे में ज़्यादा जानने के लिए, मिलते-जुलते पैटर्न और यूआरएल को बाहर रखने के तरीके के बारे में जानने के लिए, मिलते-जुलते पैटर्न और ग्लोब देखें.
css स्ट्रिंग का कलेक्शन ज़रूरी नहीं. उन सीएसएस फ़ाइलों की सूची जिन्हें मिलते-जुलते पेजों में इंजेक्ट किया जाना है. इन्हें उसी क्रम में इंजेक्ट किया जाता है जिस क्रम में वे इस अरे में दिखते हैं. पेज के लिए किसी भी डीओएम को बनाने या दिखाने से पहले इन्हें इंजेक्ट किया जाता है.
js कलर का कलेक्शन ज़रूरी नहीं. मिलते-जुलते पेजों में इंजेक्ट की जाने वाली JavaScript फ़ाइलों की सूची. फ़ाइलों को उसी क्रम में इंजेक्ट किया जाता है जिस क्रम में वे इस अरे में दिखती हैं. इस सूची की हर स्ट्रिंग में, एक्सटेंशन की रूट डायरेक्ट्री में मौजूद किसी संसाधन का रिलेटिव पाथ शामिल होना चाहिए. लीडिंग स्लैश (`/`) को अपने-आप कम कर दिया जाता है.
run_at RunAt ज़रूरी नहीं. इससे पता चलता है कि स्क्रिप्ट को पेज में कब इंजेक्ट किया जाना चाहिए. डिफ़ॉल्ट document_idle.
match_about_blank boolean ज़रूरी नहीं. स्क्रिप्ट को किसी ऐसे about:blank फ़्रेम में इंजेक्ट करना चाहिए या नहीं जहां पैरंट या ओपनर फ़्रेम, matches में बताए गए किसी पैटर्न से मेल खाता हो. डिफ़ॉल्ट तौर पर, यह 'गलत' पर सेट होता है.
match_origin_as_fallback boolean ज़रूरी नहीं. स्क्रिप्ट को ऐसे फ़्रेम में इंजेक्ट करना चाहिए या नहीं जिन्हें किसी मेल खाने वाले ऑरिजिन से बनाया गया था, लेकिन हो सकता है कि जिनका यूआरएल या ऑरिजिन पैटर्न से सीधे तौर पर मेल न खाता हो. इनमें अलग-अलग स्कीम वाले फ़्रेम शामिल होते हैं, जैसे कि about:, data:, blob:, और filesystem:. मिलते-जुलते फ़्रेम में इंजेक्ट करना भी देखें.
world ExecutionWorld ज़रूरी नहीं. स्क्रिप्ट के लिए JavaScript की दुनिया जिसे काम करना है. डिफ़ॉल्ट वैल्यू ISOLATED होती है. अलग-अलग जगहों पर काम करना भी देखें.

डाइनैमिक एलानों के साथ इंजेक्ट करें

डाइनैमिक कॉन्टेंट स्क्रिप्ट तब काम आती हैं, जब कॉन्टेंट स्क्रिप्ट के मैच पैटर्न के बारे में जानकारी मौजूद न हो या जब कॉन्टेंट स्क्रिप्ट को हमेशा जाने-पहचाने होस्ट पर इंजेक्ट नहीं किया जाना चाहिए.

Chrome 96 में लॉन्च की गई जानकारी, स्टैटिक जानकारी जैसी ही होती है. हालांकि, कॉन्टेंट स्क्रिप्ट ऑब्जेक्ट को Chrome में manifest.json के बजाय, chrome.scripting नेमस्पेस में रजिस्टर किया जाता है. स्क्रिप्टिंग एपीआई, एक्सटेंशन डेवलपर को ये काम भी करने देता है:

स्टैटिक एलानों की तरह, डाइनैमिक एलानों में JavaScript फ़ाइलें, सीएसएस फ़ाइलें या दोनों शामिल हो सकते हैं.

service-worker.js (सर्विस-worker.js)

chrome.scripting
  .registerContentScripts([{
    id: "session-script",
    js: ["content.js"],
    persistAcrossSessions: false,
    matches: ["*://example.com/*"],
    runAt: "document_start",
  }])
  .then(() => console.log("registration complete"))
  .catch((err) => console.warn("unexpected error", err))

service-worker.js (सर्विस-worker.js)

chrome.scripting
  .updateContentScripts([{
    id: "session-script",
    excludeMatches: ["*://admin.example.com/*"],
  }])
  .then(() => console.log("registration updated"));

service-worker.js (सर्विस-worker.js)

chrome.scripting
  .getRegisteredContentScripts()
  .then(scripts => console.log("registered content scripts", scripts));

service-worker.js (सर्विस-worker.js)

chrome.scripting
  .unregisterContentScripts({ ids: ["session-script"] })
  .then(() => console.log("un-registration complete"));

प्रोग्राम के हिसाब से इंजेक्ट करें

ऐसे कॉन्टेंट स्क्रिप्ट के लिए प्रोग्रामैटिक इंजेक्शन का इस्तेमाल करें जिन्हें किसी इवेंट या खास मौकों पर चलाए जाने की ज़रूरत होती है.

प्रोग्राम के हिसाब से कॉन्टेंट स्क्रिप्ट इंजेक्ट करने के लिए, आपके एक्सटेंशन को उस पेज के लिए होस्ट की अनुमतियों की ज़रूरत होती है जिसमें स्क्रिप्ट इंजेक्ट करने की कोशिश की जा रही है. होस्ट की अनुमतियों के लिए, आपके एक्सटेंशन के मेनिफ़ेस्ट के हिस्से के तौर पर अनुरोध करके या कुछ समय के लिए "activeTab" का इस्तेमाल किया जा सकता है.

नीचे दिए गए, किसी ActiveTab पर आधारित एक्सटेंशन के अलग-अलग वर्शन दिए गए हैं.

manifest.json:

{
  "name": "My extension",
  ...
  "permissions": [
    "activeTab",
    "scripting"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_title": "Action Button"
  }
}

कॉन्टेंट स्क्रिप्ट को फ़ाइलों के तौर पर इंजेक्ट किया जा सकता है.

content-script.js


document.body.style.backgroundColor = "orange";

service-worker.js:

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    files: ["content-script.js"]
  });
});

इसके अलावा, फ़ंक्शन के मुख्य हिस्से को कॉन्टेंट स्क्रिप्ट के तौर पर इंजेक्ट और एक्ज़ीक्यूट किया जा सकता है.

service-worker.js:

function injectedFunction() {
  document.body.style.backgroundColor = "orange";
}

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target : {tabId : tab.id},
    func : injectedFunction,
  });
});

ध्यान रखें कि इंजेक्ट किया गया फ़ंक्शन, chrome.scripting.executeScript() कॉल में रेफ़र किए गए फ़ंक्शन की कॉपी है, न कि ओरिजनल फ़ंक्शन की. इस वजह से, फ़ंक्शन का मुख्य हिस्सा खुद में शामिल होना चाहिए. फ़ंक्शन के बाहर मौजूद वैरिएबल के रेफ़रंस की वजह से, कॉन्टेंट स्क्रिप्ट ReferenceError को दिखाएगा.

फ़ंक्शन के तौर पर इंजेक्ट करते समय, फ़ंक्शन में आर्ग्युमेंट पास भी किए जा सकते हैं.

service-worker.js (सर्विस-worker.js)

function injectedFunction(color) {
  document.body.style.backgroundColor = color;
}

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target : {tabId : tab.id},
    func : injectedFunction,
    args : [ "orange" ],
  });
});

मैच और ग्लोब को शामिल न करें

चुनिंदा पेज को मैच कराने की सुविधा को पसंद के मुताबिक बनाने के लिए, इन फ़ील्ड को डिक्लेरेटिव रजिस्ट्रेशन में शामिल करें.

नाम टाइप ब्यौरा
exclude_matches स्ट्रिंग का कलेक्शन ज़रूरी नहीं. इसमें ऐसे पेज शामिल नहीं हैं जिनमें यह कॉन्टेंट स्क्रिप्ट, आम तौर पर इंजेक्ट की जाती है. इन स्ट्रिंग के सिंटैक्स के बारे में ज़्यादा जानने के लिए, मिलते-जुलते पैटर्न देखें.
include_globs स्ट्रिंग का कलेक्शन ज़रूरी नहीं. सिर्फ़ उन यूआरएल को शामिल करने के लिए, जो इस ग्लोब से मिलते-जुलते हैं, matches के बाद लागू किए गए. इसका मकसद, @include Gressmonkey कीवर्ड को एम्युलेट करना है.
exclude_globs स्ट्रिंग का अरे ज़रूरी नहीं. इस ग्लोब से मेल खाने वाले यूआरएल को बाहर रखने के लिए, matches के बाद लागू किया गया. इसका मकसद, @exclude Gressmonkey कीवर्ड को एम्युलेट करना है.

अगर नीचे दी गई दोनों बातें सही हैं, तो कॉन्टेंट स्क्रिप्ट को किसी पेज में डाला जाएगा:

  • इसका यूआरएल किसी भी matches पैटर्न और किसी भी include_globs पैटर्न से मैच करता है.
  • यूआरएल, exclude_matches या exclude_globs पैटर्न से भी मेल नहीं खाता. matches प्रॉपर्टी ज़रूरी है, इसलिए exclude_matches, include_globs, और exclude_globs का इस्तेमाल सिर्फ़ यह तय करने के लिए किया जा सकता है कि किन पेजों पर असर पड़ेगा.

नीचे दिया गया एक्सटेंशन, कॉन्टेंट स्क्रिप्ट को https://www.nytimes.com/health में इंजेक्ट करता है, लेकिन https://www.nytimes.com/business में नहीं .

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "exclude_matches": ["*://*/*business*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}

service-worker.js (सर्विस-worker.js)

chrome.scripting.registerContentScripts([{
  id : "test",
  matches : [ "https://*.nytimes.com/*" ],
  excludeMatches : [ "*://*/*business*" ],
  js : [ "contentScript.js" ],
}]);

ग्लोब प्रॉपर्टी, मैच पैटर्न से अलग और ज़्यादा सुविधाजनक सिंटैक्स को फ़ॉलो करती हैं. स्वीकार किए जाने वाले ग्लोब स्ट्रिंग ऐसे यूआरएल होते हैं जिनमें "वाइल्डकार्ड" तारे और सवाल के निशान हो सकते हैं. स्टार का निशान (*) खाली स्ट्रिंग के साथ-साथ, किसी भी लंबाई वाली किसी भी स्ट्रिंग से मेल खाता है. वहीं, सवाल का निशान (?) किसी एक वर्ण से मेल खाता है.

उदाहरण के लिए, ग्लोब https://???.example.com/foo/\* इनमें से किसी से भी मेल खाता है:

  • https://www.example.com/foo/bar
  • https://the.example.com/foo/

हालांकि, यह नीचे दी गई जानकारी से मेल नहीं खाता है:

  • https://my.example.com/foo/bar
  • https://example.com/foo/
  • https://www.example.com/foo

यह एक्सटेंशन, कॉन्टेंट स्क्रिप्ट को https://www.nytimes.com/arts/index.html और https://www.nytimes.com/jobs/index.htm* में इंजेक्ट करता है, लेकिन https://www.nytimes.com/sports/index.html में नहीं:

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "include_globs": ["*nytimes.com/???s/*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}

यह एक्सटेंशन, कॉन्टेंट स्क्रिप्ट को https://history.nytimes.com और https://.nytimes.com/history में इंजेक्ट करता है, लेकिन https://science.nytimes.com या https://www.nytimes.com/science में नहीं:

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "exclude_globs": ["*science*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}

सही दायरा हासिल करने के लिए, इनमें से कोई एक, सभी या कुछ कैटगरी शामिल की जा सकती हैं.

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "exclude_matches": ["*://*/*business*"],
      "include_globs": ["*nytimes.com/???s/*"],
      "exclude_globs": ["*science*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}

रनटाइम

run_at फ़ील्ड से यह कंट्रोल किया जाता है कि वेब पेज में JavaScript फ़ाइलों को कब इंजेक्ट किया जाए. इसके लिए, प्राथमिकता और डिफ़ॉल्ट वैल्यू "document_idle" है. अन्य संभावित वैल्यू के लिए, RunAt टाइप देखें.

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "run_at": "document_idle",
      "js": ["contentScript.js"]
    }
  ],
  ...
}

service-worker.js (सर्विस-worker.js)

chrome.scripting.registerContentScripts([{
  id : "test",
  matches : [ "https://*.nytimes.com/*" ],
  runAt : "document_idle",
  js : [ "contentScript.js" ],
}]);
नाम टाइप ब्यौरा
document_idle स्ट्रिंग सुझाव दें. जहां भी हो सके, "document_idle" का इस्तेमाल करें.

ब्राउज़र "document_end" के बीच से लेकर window.onload इवेंट के ट्रिगर होने के तुरंत बाद, स्क्रिप्ट इंजेक्ट करने का समय चुनता है. डेटा डालने का सटीक समय इस बात पर निर्भर करता है कि दस्तावेज़ कितना मुश्किल है और इसे लोड होने में कितना समय लग रहा है. साथ ही, इसे पेज लोड होने की स्पीड के हिसाब से ऑप्टिमाइज़ किया जाता है.

"document_idle" पर चल रही कॉन्टेंट स्क्रिप्ट को window.onload इवेंट में सुनने की ज़रूरत नहीं है. डीओएम के पूरा होने के बाद ही वे ट्रिगर होंगी. अगर किसी स्क्रिप्ट को window.onload के बाद चलाना ज़रूरी है, तो एक्सटेंशन यह जांच कर सकता है कि document.readyState प्रॉपर्टी का इस्तेमाल करके, onload पहले ही ट्रिगर हो चुका है या नहीं.
document_start स्ट्रिंग css में से किसी भी फ़ाइल के बाद स्क्रिप्ट इंजेक्ट की जाती हैं. हालांकि, किसी दूसरे DOM के बनने या कोई दूसरी स्क्रिप्ट चलाने से पहले.
document_end स्ट्रिंग डीओएम के पूरा होने के तुरंत बाद, स्क्रिप्ट इंजेक्ट की जाती हैं. हालांकि, इमेज और फ़्रेम जैसे सबरिसॉर्स के लोड होने से पहले ही स्क्रिप्ट इंजेक्ट की जाती हैं.

फ़्रेम तय करें

"all_frames" फ़ील्ड की मदद से, एक्सटेंशन यह तय कर सकता है कि JavaScript और सीएसएस फ़ाइलों को तय किए गए यूआरएल की ज़रूरत से मेल खाने वाले सभी फ़्रेम में डाला जाना चाहिए या टैब में सिर्फ़ सबसे ऊपर वाले फ़्रेम में.

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "all_frames": true,
      "js": ["contentScript.js"]
    }
  ],
  ...
}

service-worker.js (सर्विस-worker.js)

chrome.scripting.registerContentScripts([{
  id: "test",
  matches : [ "https://*.nytimes.com/*" ],
  allFrames : true,
  js : [ "contentScript.js" ],
}]);
नाम टाइप ब्यौरा
all_frames boolean ज़रूरी नहीं. डिफ़ॉल्ट तौर पर false का मतलब है कि सिर्फ़ टॉप फ़्रेम मैच होता है.

अगर true तय किया गया है, तो सभी फ़्रेम इंजेक्ट किए जाएंगे. भले ही, टैब में फ़्रेम सबसे ऊपर मौजूद फ़्रेम न हो. यूआरएल की ज़रूरी शर्तों के लिए, हर फ़्रेम की अलग-अलग जांच की जाती है. अगर यूआरएल की ज़रूरी शर्तें पूरी नहीं होती हैं, तो यह चाइल्ड फ़्रेम में इंजेक्ट नहीं किया जाएगा.

एक्सटेंशन ऐसे फ़्रेम में स्क्रिप्ट चलाना चाह सकते हैं जो मिलते-जुलते फ़्रेम से जुड़े हों, लेकिन वे खुद मैच नहीं करते. ऐसा तब होता है, जब ऐसे फ़्रेम वाले यूआरएल जिन्हें मिलते-जुलते फ़्रेम से बनाया गया हो, लेकिन जिनके यूआरएल स्क्रिप्ट के बताए गए पैटर्न से मेल न खाते हों, ऐसे फ़्रेम के लिए ऐसा होता है.

ऐसा तब होता है, जब कोई एक्सटेंशन ऐसे यूआरएल के साथ फ़्रेम इंजेक्ट करना चाहता है जिनमें about:, data:, blob:, और filesystem: स्कीम हों. इन मामलों में, यूआरएल कॉन्टेंट स्क्रिप्ट के पैटर्न से मैच नहीं करेगा और about: और data: के मामले में, यूआरएल में पैरंट यूआरएल या ऑरिजिन शामिल न करें, जैसे कि about:blank या data:text/html,<html>Hello, World!</html> में. हालांकि, ये फ़्रेम अब भी बनाने के फ़्रेम से जोड़े जा सकते हैं.

इन फ़्रेम में इंजेक्ट करने के लिए, एक्सटेंशन मेनिफ़ेस्ट में कॉन्टेंट स्क्रिप्ट स्पेसिफ़िकेशन में "match_origin_as_fallback" प्रॉपर्टी के बारे में बता सकते हैं.

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.google.com/*"],
      "match_origin_as_fallback": true,
      "js": ["contentScript.js"]
    }
  ],
  ...
}

अगर कोई फ़्रेम तय किया गया है और उसे true पर सेट किया गया है, तो Chrome, फ़्रेम के यूआरएल के बजाय, यह तय करने के लिए कि फ़्रेम मेल खाता है या नहीं, फ़्रेम के शुरू करने वाले की शुरुआत करने वाले व्यक्ति की जांच करेगा. ध्यान दें कि यह टारगेट फ़्रेम के ऑरिजिन से भी अलग हो सकता है (उदाहरण, data: यूआरएल का ऑरिजिन शून्य है).

फ़्रेम को शुरू करने वाला फ़्रेम वह फ़्रेम है जिसने टारगेट फ़्रेम को बनाया या नेविगेट किया. हालांकि, यह आम तौर पर डायरेक्ट पैरंट या ओपनर होता है, लेकिन यह ज़रूरी नहीं है (जैसा कि किसी iframe में iframe नेविगेट करने वाले फ़्रेम के मामले में होता है).

इसकी वजह यह है कि इनिशिएटर फ़्रेम के ऑरिजिन की तुलना की जाती है, इसलिए इनिशिएटर फ़्रेम उस ऑरिजिन के किसी भी पाथ पर हो सकता है. इस पहलू को साफ़ तौर पर बताने के लिए, Chrome को ऐसी सभी कॉन्टेंट स्क्रिप्ट की ज़रूरत होती है जिनके साथ "match_origin_as_fallback" को true पर सेट किया गया हो, ताकि * का पाथ भी बताया जा सके.

जब "match_origin_as_fallback" और "match_about_blank", दोनों के बारे में बताया गया हो, तो "match_origin_as_fallback" को प्राथमिकता मिलती है.

एम्बेड किए गए पेज से कम्यूनिकेशन की जानकारी

हालांकि, कॉन्टेंट स्क्रिप्ट और उन्हें होस्ट करने वाले पेजों को चलाने का एनवायरमेंट एक-दूसरे से अलग होता है, लेकिन वे पेज के डीओएम का ऐक्सेस शेयर करते हैं. अगर पेज, कॉन्टेंट स्क्रिप्ट या कॉन्टेंट स्क्रिप्ट के ज़रिए एक्सटेंशन के साथ कम्यूनिकेशन करना चाहता है, तो ऐसा शेयर किए गए DOM के ज़रिए किया जाना चाहिए.

ऐसा करने के लिए, window.postMessage() का इस्तेमाल करें:

content-script.js

var port = chrome.runtime.connect();

window.addEventListener("message", (event) => {
  // We only accept messages from ourselves
  if (event.source !== window) {
    return;
  }

  if (event.data.type && (event.data.type === "FROM_PAGE")) {
    console.log("Content script received: " + event.data.text);
    port.postMessage(event.data.text);
  }
}, false);

example.js

document.getElementById("theButton").addEventListener("click", () => {
  window.postMessage(
      {type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);

गैर-एक्सटेंशन पेज, example.html, खुद पर ही मैसेज पोस्ट करता है. इस मैसेज को इंटरसेप्ट किया जाता है और कॉन्टेंट स्क्रिप्ट की मदद से इसका पता लगाता है. इसके बाद, इसे एक्सटेंशन प्रोसेस में पोस्ट कर दिया जाता है. इस तरह से, पेज एक्सटेंशन प्रोसेस के लिए कम्यूनिकेशन की एक लाइन बनाता है. इसी तरह के तरीकों से ऐसा हो सकता है.

एक्सटेंशन फ़ाइलों को ऐक्सेस करना

किसी कॉन्टेंट स्क्रिप्ट से एक्सटेंशन फ़ाइल ऐक्सेस करने के लिए, chrome.runtime.getURL() को कॉल करके, एक्सटेंशन ऐसेट का पूरा यूआरएल पाएं, जैसा कि यहां दिए गए उदाहरण (content.js) में दिखाया गया है:

content-script.js

let image = chrome.runtime.getURL("images/my_image.png")

सीएसएस फ़ाइल में फ़ॉन्ट या इमेज इस्तेमाल करने के लिए, @@extension_id का इस्तेमाल करके यूआरएल बनाएं, जैसा कि इस उदाहरण (content.css) में दिखाया गया है:

content.css

body {
 background-image:url('chrome-extension://__MSG_@@extension_id__/background.png');
}

@font-face {
 font-family: 'Stint Ultra Expanded';
 font-style: normal;
 font-weight: 400;
 src: url('chrome-extension://__MSG_@@extension_id__/fonts/Stint Ultra Expanded.woff') format('woff');
}

manifest.json फ़ाइल में, सभी एसेट को वेब से ऐक्सेस किए जा सकने वाले संसाधन के तौर पर बताया जाना चाहिए:

manifest.json

{
 ...
 "web_accessible_resources": [
   {
     "resources": [ "images/*.png" ],
     "matches": [ "https://example.com/*" ]
   },
   {
     "resources": [ "fonts/*.woff" ],
     "matches": [ "https://example.com/*" ]
   }
 ],
 ...
}

सुरक्षित रहें

एकांत में रहने वाली दुनिया सुरक्षा की एक लेयर उपलब्ध कराती है, लेकिन कॉन्टेंट स्क्रिप्ट का इस्तेमाल करने से किसी एक्सटेंशन और वेब पेज में जोखिम की आशंकाएं पैदा हो सकती हैं. अगर कॉन्टेंट स्क्रिप्ट को किसी अलग वेबसाइट से कॉन्टेंट मिलता है, जैसे कि fetch() को कॉल करने पर, तो कॉन्टेंट को इंजेक्ट करने से पहले, उसे क्रॉस-साइट स्क्रिप्टिंग हमलों के ख़िलाफ़ फ़िल्टर कर लें. "man-in-the-middle" हमलों से बचने के लिए, सिर्फ़ एचटीटीपीएस का इस्तेमाल करके बातचीत की जा सकती है.

नुकसान पहुंचाने वाले वेब पेजों को फ़िल्टर करना न भूलें. उदाहरण के लिए, ये पैटर्न खतरनाक हैं और मेनिफ़ेस्ट V3 में इनकी अनुमति नहीं दी गई है:

यह न करें

content-script.js

const data = document.getElementById("json-data");
// WARNING! Might be evaluating an evil script!
const parsed = eval("(" + data + ")");
यह न करें

content-script.js

const elmt_id = ...
// WARNING! elmt_id might be '); ... evil script ... //'!
window.setTimeout("animate(" + elmt_id + ")", 200);

इसके बजाय, ऐसे सुरक्षित एपीआई को प्राथमिकता दें जो स्क्रिप्ट नहीं चलाते:

ऐसा करें

content-script.js

const data = document.getElementById("json-data")
// JSON.parse does not evaluate the attacker's scripts.
const parsed = JSON.parse(data);
ऐसा करें

content-script.js

const elmt_id = ...
// The closure form of setTimeout does not evaluate scripts.
window.setTimeout(() => animate(elmt_id), 200);