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

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

कॉन्टेंट स्क्रिप्ट की सुविधाओं के बारे में जानकारी

कॉन्टेंट स्क्रिप्ट, मैसेज को शेयर करके, अपने पैरंट एक्सटेंशन में इस्तेमाल किए गए Chrome API को ऐक्सेस कर सकती हैं एक्सटेंशन के साथ. वे chrome.runtime.getURL() के साथ किसी एक्सटेंशन फ़ाइल के यूआरएल को भी ऐक्सेस कर सकते हैं और नतीजे का इस्तेमाल अन्य यूआरएल की तरह कर सकते हैं.

// Code for displaying EXTENSION_DIR/images/myimage.png:
var imgURL = chrome.runtime.getURL("images/myimage.png");
document.getElementById("someImage").src = imgURL;

इसके अलावा, कॉन्टेंट स्क्रिप्ट इन Chrome API को सीधे तौर पर ऐक्सेस कर सकती है:

कॉन्टेंट स्क्रिप्ट, अन्य एपीआई को सीधे ऐक्सेस नहीं कर सकतीं.

अलग-अलग वर्ल्ड में काम करना

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

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

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

वह एक्सटेंशन यह कॉन्टेंट स्क्रिप्ट इंजेक्ट कर सकता है.

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

बटन दबाने पर दोनों अलर्ट दिखेंगे.

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

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

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

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

प्रोग्रामैटिक इंजेक्शन का इस्तेमाल उन कॉन्टेंट स्क्रिप्ट के लिए करें जिन्हें खास मौकों पर चलाना है.

प्रोग्राम के हिसाब से कॉन्टेंट दिखाने वाली स्क्रिप्ट इंजेक्ट करने के लिए, मेनिफ़ेस्ट में activeTab की अनुमति दें. इससे सक्रिय साइट के होस्ट का सुरक्षित ऐक्सेस और टैब का कुछ समय के लिए ऐक्सेस मिल जाता है अनुमति के साथ, बिना बताए कॉन्टेंट स्क्रिप्ट को मौजूदा ऐक्टिव टैब पर चलने के लिए चालू करना क्रॉस-ऑरिजिन अनुमतियां.

{
  "name": "My extension",
  ...
  "permissions": [
    "activeTab"
  ],
  ...
}

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

chrome.runtime.onMessage.addListener(
  function(message, callback) {
    if (message == "changeColor"){
      chrome.tabs.executeScript({
        code: 'document.body.style.backgroundColor="orange"'
      });
    }
  });

इसके अलावा, पूरी फ़ाइल को इंजेक्ट किया जा सकता है.

chrome.runtime.onMessage.addListener(
  function(message, callback) {
    if (message == "runContentScript"){
      chrome.tabs.executeScript({
        file: 'contentScript.js'
      });
    }
  });

एनोटेशन के ज़रिए इंजेक्ट करना

उन कॉन्टेंट स्क्रिप्ट के लिए, डिक्लेरेटिव इंजेक्शन का इस्तेमाल करें जिन्हें खास पेजों पर अपने-आप चलाया जाना चाहिए.

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

{
 "name": "My extension",
 ...
 "content_scripts": [
   {
     "matches": ["http://*.nytimes.com/*"],
     "css": ["myStyles.css"],
     "js": ["contentScript.js"]
   }
 ],
 ...
}
नाम टाइप ब्यौरा
matches {: #matches } स्ट्रिंग का कलेक्शन ज़रूरी है. इससे यह तय होता है कि इस कॉन्टेंट स्क्रिप्ट को किन पेजों में इंजेक्ट किया जाएगा. इन स्ट्रिंग के सिंटैक्स के बारे में ज़्यादा जानकारी के लिए, मैच पैटर्न देखें. साथ ही, यूआरएल को बाहर रखने के तरीके के बारे में जानने के लिए, मैच पैटर्न और ग्लोब देखें.
css {: #css } स्ट्रिंग का कलेक्शन ज़रूरी नहीं. मिलते-जुलते पेजों पर डाली जाने वाली सीएसएस फ़ाइलों की सूची. इन्हें उसी क्रम में इंजेक्ट किया जाता है जिस क्रम में ये इस कलेक्शन में दिखते हैं. पेज के लिए कोई डीओएम बनाने या दिखाने से पहले.
js {: #js } स्ट्रिंग का कलेक्शन ज़रूरी नहीं. मिलते-जुलते पेजों पर डाली जाने वाली JavaScript फ़ाइलों की सूची. इन्हें उसी क्रम में डाला जाता है जिस क्रम में ये इस अरे में दिखते हैं.
match_about_blank {: #match_about_blank } बूलियन ज़रूरी नहीं. क्या स्क्रिप्ट को about:blank फ़्रेम में इंजेक्ट करना चाहिए, जहां पैरंट या ओपनर फ़्रेम, matches में बताए गए किसी पैटर्न से मेल खाता हो. डिफ़ॉल्ट तौर पर, यह false पर सेट होती है.

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

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

नाम टाइप ब्यौरा
exclude_matches {: #exclude_matches } स्ट्रिंग का कलेक्शन ज़रूरी नहीं. उन पेजों को बाहर रखता है जिनमें इस कॉन्टेंट स्क्रिप्ट को इंजेक्ट किया जाना चाहिए. इन स्ट्रिंग के सिंटैक्स की ज़्यादा जानकारी के लिए, मैच पैटर्न देखें.
include_globs {: #include_globs } स्ट्रिंग का कलेक्शन ज़रूरी नहीं. सिर्फ़ उन यूआरएल को शामिल करने के लिए matches के बाद लागू किया जाता है जो इस ग्लोब से मेल खाते हैं. इसका मकसद, @include Greasemonkey कीवर्ड को एम्युलेट करना है.
exclude_globs {: #exclude_globs } स्ट्रिंग का कलेक्शन ज़रूरी नहीं. इस ग्लोब से मेल खाने वाले यूआरएल को बाहर रखने के लिए, matches के बाद लागू किया गया. इसका मकसद, @excludeGreasemonkey कीवर्ड को एम्युलेट करना है.

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

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

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

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

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

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

  • http:// www .example.com/foo /bar
  • http:// .example.com/foo /

हालांकि, यह इनसे मेल नहीं खाता:

  • http:// मेरा .example.com/foo/bar
  • http:// example .com/foo/
  • http://www.example.com/foo

यह एक्सटेंशन, कॉन्टेंट स्क्रिप्ट को http:/www.nytimes.com/ art /index.html और http://www.nytimes.com/ नौकरी /index.html लेकिन http://www.nytimes.com/ खेल में नहीं /index.html.

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

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

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

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

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

रनटाइम

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

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "run_at": "document_idle",
      "js": ["contentScript.js"]
    }
  ],
  ...
}
नाम टाइप ब्यौरा
document_idle {: #document_idle } स्ट्रिंग पसंदीदा. जब भी हो सके, "document_idle" का इस्तेमाल करें.

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

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

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

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

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "all_frames": true,
      "js": ["contentScript.js"]
    }
  ],
  ...
}
नाम टाइप ब्यौरा
all_frames {: #all_frames } बूलियन ज़रूरी नहीं. डिफ़ॉल्ट रूप से false पर सेट होता है. इसका मतलब है कि सिर्फ़ सबसे ऊपर मौजूद फ़्रेम से मैच किया जाएगा.

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

एम्बेड किए गए पेज से बातचीत

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

उदाहरण के लिए, window.postMessage का इस्तेमाल करके:

var port = chrome.runtime.connect();

window.addEventListener("message", function(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);
document.getElementById("theButton").addEventListener("click",
    function() {
  window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");
}, false);

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

खाता सुरक्षित रखना

अलग-अलग वर्ल्ड, सुरक्षा की एक लेयर देते हैं. हालांकि, कॉन्टेंट स्क्रिप्ट का इस्तेमाल करने से, एक्सटेंशन और वेब पेज में कमज़ोरियां पैदा हो सकती हैं. अगर कॉन्टेंट स्क्रिप्ट को किसी दूसरी वेबसाइट से कॉन्टेंट मिलता है, जैसे कि XMLHttpRequest बनाना, तो कॉन्टेंट को इंजेक्ट करने से पहले, क्रॉस-साइट स्क्रिप्टिंग अटैक को फ़िल्टर करने में सावधानी बरतें. बचने के लिए, सिर्फ़ एचटीटीपीएस का इस्तेमाल करके बातचीत करें &quot;man-in-the-middle&quot; हमले.

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

var data = document.getElementById("json-data")
// WARNING! Might be evaluating an evil script!
var parsed = eval("(" + data + ")")
var elmt_id = ...
// WARNING! elmt_id might be "); ... evil script ... //"!
window.setTimeout("animate(" + elmt_id + ")", 200);

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

var data = document.getElementById("json-data")
// JSON.parse does not evaluate the attacker's scripts.
var parsed = JSON.parse(data);
var elmt_id = ...
// The closure form of setTimeout does not evaluate scripts.
window.setTimeout(function() {
  animate(elmt_id);
}, 200);