कॉन्टेंट स्क्रिप्ट ऐसी फ़ाइलें होती हैं जो वेब पेजों के कॉन्टेक्स्ट में चलती हैं. स्टैंडर्ड डॉक्यूमेंट ऑब्जेक्ट मॉडल (DOM) का इस्तेमाल करके, ये एक्सटेंशन उन वेब पेजों की जानकारी पढ़ सकते हैं जिन पर ब्राउज़र जाता है. साथ ही, उनमें बदलाव कर सकते हैं और अपने पैरंट एक्सटेंशन को जानकारी भेज सकते हैं.
कॉन्टेंट स्क्रिप्ट की क्षमताओं के बारे में जानकारी
कॉन्टेंट स्क्रिप्ट, सीधे तौर पर इन एक्सटेंशन एपीआई को ऐक्सेस कर सकती हैं:
dom
i18n
storage
runtime.connect()
runtime.getManifest()
runtime.getURL()
runtime.id
runtime.onConnect
runtime.onMessage
runtime.sendMessage()
कॉन्टेंट स्क्रिप्ट, अन्य एपीआई को सीधे तौर पर ऐक्सेस नहीं कर सकतीं. हालांकि, वे आपके एक्सटेंशन के अन्य हिस्सों के साथ मैसेज का आदान-प्रदान करके, इन फ़ाइलों को परोक्ष रूप से ऐक्सेस कर सकते हैं.
कॉन्टेंट स्क्रिप्ट से, अपने एक्सटेंशन में मौजूद अन्य फ़ाइलों को भी ऐक्सेस किया जा सकता है. इसके लिए, fetch()
जैसे एपीआई का इस्तेमाल करें. इसके लिए, आपको उन्हें वेब पर ऐक्सेस किए जा सकने वाले संसाधन के तौर पर घोषित करना होगा. ध्यान दें कि इससे रिसॉर्स, उसी साइट पर चलने वाली किसी भी पहले पक्ष या तीसरे पक्ष की स्क्रिप्ट के लिए भी उपलब्ध हो जाते हैं.
आइसोलेटेड वर्ल्ड में काम करना
कॉन्टेंट स्क्रिप्ट, अलग-अलग काम करती हैं. इससे किसी कॉन्टेंट स्क्रिप्ट को अपने 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 |
बूलियन | ज़रूरी नहीं. क्या स्क्रिप्ट को किसी about:blank फ़्रेम में इंजेक्ट किया जाना चाहिए, जहां पैरंट या ओपनर फ़्रेम, matches में बताए गए किसी एक पैटर्न से मेल खाता हो. डिफ़ॉल्ट रूप से, यह 'गलत' पर सेट होती है. |
match_origin_as_fallback |
बूलियन |
ज़रूरी नहीं. क्या स्क्रिप्ट को उन फ़्रेम में इंजेक्ट करना चाहिए जिन्हें मैचिंग ऑरिजिन ने बनाया है, लेकिन जिनका यूआरएल या ऑरिजिन पैटर्न से सीधे तौर पर मेल नहीं खाता है. इनमें अलग-अलग स्कीम वाले फ़्रेम शामिल हैं. जैसे, about: , data: , blob: , और filesystem: . मिलते-जुलते फ़्रेम में स्क्रिप्ट डालना भी देखें.
|
world |
ExecutionWorld |
ज़रूरी नहीं. JavaScript का वह एनवायरमेंट जिसमें स्क्रिप्ट को एक्ज़ीक्यूट किया जाता है. यह डिफ़ॉल्ट रूप से ISOLATED पर सेट होता है. यह भी देखें: आइसोलेटेड वर्ल्ड में काम करना.
|
डाइनैमिक एलान के साथ इंजेक्ट करना
डाइनैमिक कॉन्टेंट स्क्रिप्ट तब काम की होती हैं, जब कॉन्टेंट स्क्रिप्ट के मैच पैटर्न के बारे में अच्छी तरह से पता न हो या जब कॉन्टेंट स्क्रिप्ट को हमेशा जाने-पहचाने होस्ट पर इंजेक्ट नहीं किया जाना चाहिए.
डाइनैमिक एलान, Chrome 96 में पेश किए गए थे. ये स्टैटिक एलान की तरह ही होते हैं. हालांकि, कॉन्टेंट स्क्रिप्ट ऑब्जेक्ट को Chrome में रजिस्टर किया जाता है. इसके लिए, manifest.json में मौजूद तरीकों के बजाय, chrome.scripting
नेमस्पेस में मौजूद तरीकों का इस्तेमाल किया जाता है. Scripting API की मदद से, एक्सटेंशन डेवलपर ये काम भी कर सकते हैं:
- कॉन्टेंट स्क्रिप्ट रजिस्टर करें.
- रजिस्टर की गई कॉन्टेंट स्क्रिप्ट की सूची पाएं.
- रजिस्टर की गई कॉन्टेंट स्क्रिप्ट की सूची को अपडेट करें.
- रजिस्टर की गई कॉन्टेंट स्क्रिप्ट हटाएं.
स्टैटिक डिक्लेरेशन की तरह, डाइनैमिक डिक्लेरेशन में JavaScript फ़ाइलें, सीएसएस फ़ाइलें या दोनों शामिल हो सकती हैं.
service-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
chrome.scripting
.updateContentScripts([{
id: "session-script",
excludeMatches: ["*://admin.example.com/*"],
}])
.then(() => console.log("registration updated"));
service-worker.js
chrome.scripting
.getRegisteredContentScripts()
.then(scripts => console.log("registered content scripts", scripts));
service-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
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
Greasemonkey कीवर्ड की नकल करना है. |
exclude_globs |
स्ट्रिंग का कलेक्शन | ज़रूरी नहीं. इस ग्लोब से मेल खाने वाले यूआरएल को बाहर रखने के लिए, matches के बाद लागू किया जाता है. इसका मकसद, @exclude
Greasemonkey कीवर्ड की नकल करना है. |
कॉन्टेंट स्क्रिप्ट को किसी पेज में तब इंजेक्ट किया जाएगा, जब ये दोनों शर्तें पूरी होती हों:
- इसका यूआरएल, किसी भी
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
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
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 इवेंट के लिए सुनने की ज़रूरत नहीं होती. ये स्क्रिप्ट, DOM पूरा होने के बाद ही चलती हैं. अगर किसी स्क्रिप्ट को window.onload के बाद ही चलना है, तो एक्सटेंशन यह देख सकता है कि onload पहले ही ट्रिगर हो चुका है या नहीं. इसके लिए, वह document.readyState प्रॉपर्टी का इस्तेमाल कर सकता है. |
document_start |
स्ट्रिंग | स्क्रिप्ट, css की किसी भी फ़ाइल के बाद इंजेक्ट की जाती हैं. हालांकि, किसी अन्य डीओएम के बनने या किसी अन्य स्क्रिप्ट के चलने से पहले ऐसा किया जाता है. |
document_end |
स्ट्रिंग | स्क्रिप्ट, DOM के पूरा होने के तुरंत बाद इंजेक्ट की जाती हैं. हालांकि, ऐसा इमेज और फ़्रेम जैसे सब-रिसोर्स लोड होने से पहले किया जाता है. |
फ़्रेम तय करना
मेनिफ़ेस्ट में बताई गई डिक्लेरेटिव कॉन्टेंट स्क्रिप्ट के लिए, "all_frames"
फ़ील्ड की मदद से एक्सटेंशन यह तय कर सकता है कि JavaScript और सीएसएस फ़ाइलों को, यूआरएल से जुड़ी ज़रूरी शर्तों को पूरा करने वाले सभी फ़्रेम में इंजेक्ट किया जाना चाहिए या सिर्फ़ टैब में सबसे ऊपर वाले फ़्रेम में इंजेक्ट किया जाना चाहिए:
manifest.json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.nytimes.com/*"],
"all_frames": true,
"js": ["contentScript.js"]
}
],
...
}
chrome.scripting.registerContentScripts(...)
का इस्तेमाल करके, प्रोग्राम के हिसाब से कॉन्टेंट स्क्रिप्ट रजिस्टर करते समय, allFrames
पैरामीटर का इस्तेमाल किया जा सकता है. इससे यह तय किया जा सकता है कि कॉन्टेंट स्क्रिप्ट को, यूआरएल से जुड़ी बताई गई ज़रूरी शर्तों को पूरा करने वाले सभी फ़्रेम में इंजेक्ट किया जाना चाहिए या सिर्फ़ टैब में सबसे ऊपर वाले फ़्रेम में. इसका इस्तेमाल सिर्फ़ tabId के साथ किया जा सकता है. अगर frameIds या documentIds तय किए गए हैं, तो इसका इस्तेमाल नहीं किया जा सकता:
service-worker.js
chrome.scripting.registerContentScripts([{
id: "test",
matches : [ "https://*.nytimes.com/*" ],
allFrames : true,
js : [ "contentScript.js" ],
}]);
मिलते-जुलते फ़्रेम में जोड़ना
एक्सटेंशन, उन फ़्रेम में स्क्रिप्ट चला सकते हैं जो मैच करने वाले फ़्रेम से जुड़े हैं, लेकिन खुद मैच नहीं करते. आम तौर पर, ऐसा तब होता है, जब किसी मैचिंग फ़्रेम से बनाए गए फ़्रेम के यूआरएल, स्क्रिप्ट के तय किए गए पैटर्न से मेल नहीं खाते.
ऐसा तब होता है, जब कोई एक्सटेंशन ऐसे फ़्रेम में इंजेक्ट करना चाहता है जिनके यूआरएल में 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/*" ]
}
],
...
}
कॉन्टेंट की सुरक्षा के बारे में नीति
आइसोलेटेड वर्ल्ड में चलने वाली कॉन्टेंट स्क्रिप्ट में, कॉन्टेंट की सुरक्षा के लिए नीति (सीएसपी) इस तरह से लागू होती है:
script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' chrome-extension://abcdefghijklmopqrstuvwxyz/; object-src 'self';
एक्सटेंशन के अन्य कॉन्टेक्स्ट पर लागू होने वाली पाबंदियों की तरह ही, यह eval()
के इस्तेमाल को रोकता है. साथ ही, बाहरी स्क्रिप्ट लोड करने से भी रोकता है.
अनपैक किए गए एक्सटेंशन के लिए, सीएसपी में लोकलहोस्ट भी शामिल होता है:
script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:* chrome-extension://abcdefghijklmopqrstuvwxyz/; object-src 'self';
जब किसी कॉन्टेंट स्क्रिप्ट को मुख्य दुनिया में इंजेक्ट किया जाता है, तब पेज की सीएसपी लागू होती है.
सुरक्षित रहें
आइसोलेटेड वर्ल्ड, सुरक्षा की एक लेयर उपलब्ध कराते हैं. हालांकि, कॉन्टेंट स्क्रिप्ट का इस्तेमाल करने से, एक्सटेंशन और वेब पेज में कमज़ोरियां पैदा हो सकती हैं. अगर कॉन्टेंट स्क्रिप्ट को किसी दूसरी वेबसाइट से कॉन्टेंट मिलता है, जैसे कि fetch()
को कॉल करके, तो कॉन्टेंट को इंजेक्ट करने से पहले, क्रॉस-साइट स्क्रिप्टिंग हमलों से बचाने के लिए, कॉन्टेंट को फ़िल्टर करें. सिर्फ़ एचटीटीपीएस पर कम्यूनिकेट करें, ताकि "man-in-the-middle" हमलों से बचा जा सके.
पक्का करें कि आपने नुकसान पहुंचाने वाले वेब पेजों को फ़िल्टर किया हो. उदाहरण के लिए, यहां दिए गए पैटर्न खतरनाक हैं. साथ ही, इन्हें Manifest 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);