कॉन्टेंट स्क्रिप्ट, एक्सटेंशन के बजाय किसी वेब पेज के कॉन्टेक्स्ट में चलती हैं. इसलिए, उन्हें अक्सर कुछ स्क्रिप्ट की ज़रूरत होती है का इस्तेमाल किया जा सकता है. उदाहरण के लिए, कोई आरएसएस रीडर एक्सटेंशन, कॉन्टेंट स्क्रिप्ट ताकि पेज पर आरएसएस फ़ीड की मौजूदगी का पता लगाया जा सके. इसके बाद, पेज के बैकग्राउंड पेज को ताकि उस पेज के लिए पेज कार्रवाई आइकॉन दिखाया जा सके.
एक्सटेंशन और उनकी कॉन्टेंट स्क्रिप्ट के बीच कम्यूनिकेशन, मैसेज पासिंग का इस्तेमाल करके किया जाता है. इनमें से कोई एक वह व्यक्ति, दूसरे व्यक्ति से भेजे गए मैसेज को सुन सकता है और उसी चैनल पर जवाब दे सकता है. मैसेज ये काम कर सकता है इसमें कोई भी मान्य JSON ऑब्जेक्ट (शून्य, बूलियन, नंबर, स्ट्रिंग, अरे या ऑब्जेक्ट) शामिल होना चाहिए. बस, अपनी एक बार किए जाने वाले अनुरोधों के लिए एपीआई और एक ज़्यादा जटिल एपीआई जो आपको लंबे समय तक बनाए रखने की अनुमति देता है कनेक्शन. इन्हें भेजना भी संभव है को संदेश भेजने का अनुरोध कर सकते हैं, यदि आपको उसका आईडी पता है, जो क्रॉस-एक्सटेंशन मैसेज सेक्शन में मैसेज पढ़ सकते हैं.
एक बार किए जाने वाले आसान अनुरोध
अगर आपको अपने एक्सटेंशन के किसी दूसरे हिस्से पर सिर्फ़ एक ही मैसेज भेजना है (और वैकल्पिक रूप से जवाब के लिए, आपको आसान तरीके से runtime.sendMessage या tabs.sendMessage का इस्तेमाल करना चाहिए . इससे आपको कॉन्टेंट स्क्रिप्ट से एक्सटेंशन में, एक बार इस्तेमाल होने वाला JSON फ़ॉर्मैट में, क्रम से लगाया जा सकने वाला मैसेज भेजने की सुविधा मिलती है. . एक वैकल्पिक कॉलबैक पैरामीटर की मदद से, आपको किसी अन्य ओर, अगर कोई हो.
कॉन्टेंट स्क्रिप्ट से अनुरोध भेजना, ऐसा दिखता है:
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
एक्सटेंशन से कॉन्टेंट स्क्रिप्ट को अनुरोध भेजना काफ़ी मिलता-जुलता दिखता है. हालांकि, इसके लिए आपको यह करना होगा तय करें कि उसे किस टैब पर भेजना है. इस उदाहरण में, कॉन्टेंट स्क्रिप्ट पर मैसेज भेजने का तरीका बताया गया है चुने हुए टैब में.
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});
रिसीविंग एंड पर, आपको runtime.onMessage इवेंट लिसनर सेट अप करना होगा, ताकि दिखाई देगा. यह कॉन्टेंट स्क्रिप्ट या एक्सटेंशन पेज पर भी ऐसा ही दिखता है.
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
}
);
ऊपर दिए गए उदाहरण में, sendResponse
को सिंक्रोनस रूप से कॉल किया गया था. अगर आपको एसिंक्रोनस तरीके से
sendResponse
, onMessage
इवेंट हैंडलर में return true;
जोड़ें.
sendResponse
कॉलबैक सिर्फ़ तब मान्य होता है, जब इसे सिंक्रोनस रूप से इस्तेमाल किया जाए या जब इवेंट हैंडलर true
के ज़रिए यह बताता हो कि वह एसिंक्रोनस तरीके से जवाब देगा. अगर कोई भी हैंडलर सही जवाब नहीं देता या sendResponse
कॉलबैक, गार्बेज इकट्ठा किया जाता है, तो sendMessage
फ़ंक्शन का कॉलबैक अपने-आप शुरू हो जाएगा.लंबे समय तक चले गए कनेक्शन
कभी-कभी ऐसी बातचीत होना मददगार होता है जो किसी एक अनुरोध और जवाब से ज़्यादा समय तक चलती है. इस स्थिति में, लंबे समय से चल रहे चैनल को अपनी कॉन्टेंट स्क्रिप्ट से , एक्सटेंशन पेज पर खोला जा सकता है या इसके उलट, runtime.connect या tabs.connect का इस्तेमाल करता है . चैनल ये काम कर सकता है: एक विकल्प का नाम रखें, ताकि आप अलग-अलग तरह के कनेक्शन के बीच अंतर कर सकें.
इसका एक उदाहरण स्वचालित फ़ॉर्म फ़िल एक्सटेंशन हो सकता है. कॉन्टेंट स्क्रिप्ट, चैनल बनाने के लिए किसी खास लॉगिन के लिए एक्सटेंशन पेज चुनें, और हर इनपुट के लिए एक्सटेंशन को एक मैसेज भेजें पेज पर मौजूद एलिमेंट. शेयर किया गया कनेक्शन, एक्सटेंशन को इस्तेमाल करने की अनुमति देता है ताकि कॉन्टेंट स्क्रिप्ट से आने वाले कई मैसेज को शेयर किया जा सके.
कनेक्शन बनाते समय, हर सिरे को एक runtime.Port ऑब्जेक्ट दिया जाता है, जिसका इस्तेमाल उस कनेक्शन से मैसेज भेजना और पाना.
कॉन्टेंट स्क्रिप्ट से चैनल खोलने और मैसेज भेजने और सुनने का तरीका यहां बताया गया है:
var port = chrome.runtime.connect({name: "knockknock"});
port.postMessage({joke: "Knock knock"});
port.onMessage.addListener(function(msg) {
if (msg.question == "Who's there?")
port.postMessage({answer: "Madame"});
else if (msg.question == "Madame who?")
port.postMessage({answer: "Madame... Bovary"});
});
एक्सटेंशन से कॉन्टेंट स्क्रिप्ट को अनुरोध भेजना काफ़ी मिलता-जुलता दिखता है. हालांकि, इसके लिए आपको यह करना होगा तय करें कि किस टैब से कनेक्ट करना है. ऊपर दिए गए उदाहरण में कनेक्ट करने के लिए कॉल को इससे बदलें tabs.connect.
इनकमिंग कनेक्शन मैनेज करने के लिए, आपको runtime.onConnect इवेंट सेट अप करना होगा लिसनर. यह कॉन्टेंट स्क्रिप्ट या एक्सटेंशन पेज पर भी ऐसा ही दिखता है. जब आपके समाचार संगठन का एक्सटेंशन "connect()" को कॉल करता है, तो यह इवेंट runtime.Port ऑब्जेक्ट के साथ सक्रिय होता है, जिन्हें आप का इस्तेमाल कनेक्शन के ज़रिए मैसेज भेजने और पाने के लिए करें. यह इस तरह से जवाब देता है: इनकमिंग कनेक्शन:
chrome.runtime.onConnect.addListener(function(port) {
console.assert(port.name == "knockknock");
port.onMessage.addListener(function(msg) {
if (msg.joke == "Knock knock")
port.postMessage({question: "Who's there?"});
else if (msg.answer == "Madame")
port.postMessage({question: "Madame who?"});
else if (msg.answer == "Madame... Bovary")
port.postMessage({question: "I don't get it."});
});
});
पोर्ट लाइफ़टाइम
पोर्ट को एक्सटेंशन के अलग-अलग हिस्सों के बीच दो-तरफ़ा कम्यूनिकेशन के तरीके के तौर पर डिज़ाइन किया गया है, जहां (टॉप-लेवल) फ़्रेम को सबसे छोटे हिस्से के तौर पर देखा जाता है. tabs.connect, runtime.connect या runtime.connectNative, पोर्ट को कॉल करने पर बनाया जाता है. इस पोर्ट का इस्तेमाल दूसरे छोर पर मैसेज भेजने के लिए तुरंत किया जा सकता है postMessage.
अगर टैब में एक से ज़्यादा फ़्रेम हैं, तो tabs.connect को कॉल करने पर runtime.onConnect इवेंट (टैब में हर फ़्रेम के लिए एक बार). इसी तरह, अगर runtime.connect का इस्तेमाल करता है, तो onConnect इवेंट कई बार (हर इवेंट के लिए एक बार) फ़्रेम में रखें).
हो सकता है कि आप कनेक्शन बंद होने का पता लगाना चाहें, उदाहरण के लिए अगर आप अलग-अलग हर ओपन पोर्ट की स्थिति. इसके लिए, runtime.Port.onDisconnect इवेंट सुना जा सकता है. यह चैनल के दूसरे हिस्से में कोई मान्य पोर्ट न होने पर इवेंट ट्रिगर होता है. ऐसा इसमें होता है इन स्थितियों में:
- दूसरे सिरे से runtime.onConnect सुनने वाला कोई व्यक्ति नहीं है.
- पोर्ट वाले टैब को अनलोड कर दिया गया है (उदाहरण के लिए, अगर टैब पर नेविगेट किया जा रहा है).
- जिस फ़्रेम पर
connect
को कॉल किया गया था उसे अनलोड कर दिया गया है. - जिन फ़्रेम को पोर्ट (runtime.onConnect की मदद से) पोर्ट मिला है वे सभी फ़्रेम अनलोड हो गए हैं.
- runtime.Port.disconnect को दूसरे सिरे से कॉल किया जाता है. ध्यान दें कि अगर
connect
कॉल के नतीजे पाने वाले के पास से कई पोर्ट में, और इनमें से किसी भी पोर्ट परdisconnect()
को कॉल किया जाता है. इसके बाद,onDisconnect
इवेंट, सिर्फ़ भेजने वाले के पोर्ट पर ट्रिगर होता है, दूसरे पोर्ट पर नहीं.
क्रॉस-एक्सटेंशन मैसेज सेवा
अपने एक्सटेंशन में अलग-अलग कॉम्पोनेंट के बीच मैसेज भेजने के अलावा, मैसेजिंग एपीआई का इस्तेमाल, अन्य एक्सटेंशन के साथ संपर्क करने के लिए किया जाता है. इससे आपको ऐसा सार्वजनिक एपीआई दिखाने में मदद मिलती है जिसे अन्य एक्सटेंशन का लाभ उठाया जा सकता है.
आने वाले अनुरोधों और कनेक्शन को सुनना, अंदरूनी केस की तरह ही है. हालांकि, आप इसका इस्तेमाल runtime.onMessageExternal या runtime.onConnectExternal तरीके का इस्तेमाल कर सकता है. यहां इसका एक उदाहरण दिया गया है हर:
// For simple requests:
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id == blocklistedExtension)
return; // don't allow this extension access
else if (request.getTargetData)
sendResponse({targetData: targetData});
else if (request.activateLasers) {
var success = activateLasers();
sendResponse({activateLasers: success});
}
});
// For long-lived connections:
chrome.runtime.onConnectExternal.addListener(function(port) {
port.onMessage.addListener(function(msg) {
// See other examples for sample onMessage handlers.
});
});
इसी तरह, किसी अन्य एक्सटेंशन को संदेश भेजना आपके एक्सटेंशन में एक्सटेंशन भेजने के समान है. सिर्फ़ इतना ही अंतर है कि आपको उस एक्सटेंशन का आईडी पास करना होगा जिससे आपको संपर्क करना है. इसके लिए उदाहरण:
// The ID of the extension we want to talk to.
var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";
// Make a simple request:
chrome.runtime.sendMessage(laserExtensionId, {getTargetData: true},
function(response) {
if (targetInRange(response.targetData))
chrome.runtime.sendMessage(laserExtensionId, {activateLasers: true});
}
);
// Start a long-running conversation:
var port = chrome.runtime.connect(laserExtensionId);
port.postMessage(...);
वेब पेजों से मैसेज भेजना
क्रॉस-एक्सटेंशन मैसेजिंग की तरह ही, आपका ऐप्लिकेशन या एक्सटेंशन भी मैसेज पा सकता है और मैसेज का जवाब दे सकता है सामान्य वेब पेजों से मैसेज. इस सुविधा का इस्तेमाल करने के लिए, आपको पहले अपनी Manifest.json में जानकारी देनी होगी आपको किन वेबसाइटों से संपर्क करना है. उदाहरण के लिए:
"externally_connectable": {
"matches": ["*://*.example.com/*"]
}
इससे मैसेजिंग एपीआई, आपके बताए गए यूआरएल पैटर्न से मेल खाने वाले किसी भी पेज पर दिखेगा. यूआरएल पैटर्न में कम से कम सेकंड-लेवल डोमेन होना चाहिए. इसका मतलब है कि होस्टनेम पैटर्न "*", "*.com", "*.co.uk", और "*.appspot.com" प्रतिबंधित हैं. वेब पेज से, किसी खास ऐप्लिकेशन को मैसेज भेजने के लिए runtime.sendMessage या runtime.connect एपीआई या एक्सटेंशन चुनें. उदाहरण के लिए:
// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";
// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
function(response) {
if (!response.success)
handleError(url);
});
अपने ऐप्स या एक्सटेंशन से, आप इसके द्वारा वेब पृष्ठों के संदेश सुन सकते हैं: runtime.onMessageExternal या runtime.onConnectExternal cross-extension से मिलते-जुलते एपीआई मैसेज सेवा. सिर्फ़ वेब पेज ही कनेक्शन शुरू कर सकता है. उदाहरण के लिए:
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.url == blocklistedWebsite)
return; // don't allow this web page access
if (request.openUrlInEditor)
openUrl(request.openUrlInEditor);
});
नेटिव मैसेज सेवा
एक्सटेंशन और ऐप्लिकेशन मैसेज का लेन-देन कर सकते हैं नेटिव मैसेजिंग होस्ट. इस सुविधा के बारे में ज़्यादा जानने के लिए, नेटिव मैसेज सेवा देखें.
सुरक्षा से जुड़ी बातें
कॉन्टेंट स्क्रिप्ट कम भरोसेमंद होती हैं
एक्सटेंशन के बैकग्राउंड पेज के मुकाबले, कॉन्टेंट स्क्रिप्ट कम भरोसेमंद होती हैं. जैसे, नुकसान पहुंचाने वाला वेब जहां कॉन्टेंट स्क्रिप्ट चलती हैं वहां रेंडरर की प्रोसेस के साथ छेड़छाड़ की जा सकती है). मान लें कि ऐसा हो सकता है कि कॉन्टेंट स्क्रिप्ट के मैसेज किसी हमलावर ने तैयार किए हों. साथ ही, यह पक्का करें कि सभी इनपुट को साफ़ करें. मान लें कि कॉन्टेंट स्क्रिप्ट को भेजा गया कोई भी डेटा, वेब पेज पर लीक हो सकता है. उन खास कार्रवाइयों का दायरा सीमित करें जो कॉन्टेंट से मिले मैसेज से ट्रिगर हो सकती हैं स्क्रिप्ट.
क्रॉस-साइट स्क्रिप्टिंग
किसी कॉन्टेंट स्क्रिप्ट या दूसरे एक्सटेंशन से मैसेज मिलते समय, आपकी स्क्रिप्ट को सावधानी बरतनी चाहिए क्रॉस-साइट स्क्रिप्टिंग का शिकार न हों. यह सलाह एक्सटेंशन के बैकग्राउंड पेज और अन्य वेब ऑरिजिन में चल रही कॉन्टेंट स्क्रिप्ट के लिए भी ऐक्सेस किया जा सकता है. खास तौर पर, खतरनाक एपीआई का इस्तेमाल करने से बचें. जैसे:
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
// WARNING! Might be evaluating an evil script!
var resp = eval("(" + response.farewell + ")");
});
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
// WARNING! Might be injecting a malicious script!
document.getElementById("resp").innerHTML = response.farewell;
});
इसके बजाय, ऐसे सुरक्षित एपीआई को प्राथमिकता दें जो स्क्रिप्ट नहीं चलाते हैं:
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(response.farewell);
});
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
// innerText does not let the attacker inject HTML elements.
document.getElementById("resp").innerText = response.farewell;
});
उदाहरण
examples/api/मैसेज में मैसेज के ज़रिए बातचीत के आसान उदाहरण देखे जा सकते हैं डायरेक्ट्री. नेटिव मैसेजिंग सैंपल से पता चलता है कि कोई Chrome ऐप्लिकेशन, खास ऐप्लिकेशन है. ज़्यादा उदाहरण देखने और सोर्स कोड देखने से जुड़ी मदद पाने के लिए, सैंपल देखें.