मैसेज पास करना

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

मैसेज पास करने के लिए दो एपीआई उपलब्ध हैं: एक एक बार के अनुरोधों के लिए और दूसरा लंबे समय तक चलने वाले कनेक्शन के लिए. दूसरे एपीआई का इस्तेमाल करके, कई मैसेज भेजे जा सकते हैं.

एक्सटेंशन के बीच मैसेज भेजने के बारे में जानकारी के लिए, एक से ज़्यादा एक्सटेंशन के बीच मैसेज भेजने की सुविधा सेक्शन देखें.

एक बार के अनुरोध

अपने एक्सटेंशन के किसी दूसरे हिस्से को एक मैसेज भेजने के लिए, runtime.sendMessage() या tabs.sendMessage() को कॉल करें. इसके अलावा, आपके पास जवाब पाने का विकल्प भी होता है. इन तरीकों से, कॉन्टेंट स्क्रिप्ट से एक्सटेंशन या एक्सटेंशन से कॉन्टेंट स्क्रिप्ट को एक बार में JSON-सीरियलाइज़ किया जा सकने वाला मैसेज भेजा जा सकता है. दोनों एपीआई, Promise ऑब्जेक्ट दिखाते हैं. यह ऑब्जेक्ट, ईमेल पाने वाले व्यक्ति के दिए गए जवाब के साथ रिज़ॉल्व होता है.

कॉन्टेंट स्क्रिप्ट से अनुरोध भेजने का तरीका यहां दिखाया गया है:

content-script.js:

(async () => {
  const response = await chrome.runtime.sendMessage({greeting: "hello"});
  // do something with response here, not outside the function
  console.log(response);
})();

जवाब

किसी मैसेज को सुनने के लिए, chrome.runtime.onMessage इवेंट का इस्तेमाल करें:

// Event listener
function handleMessages(message, sender, sendResponse) {
  if (message !== 'get-status') return;

  fetch('https://example.com')
    .then((response) => sendResponse({statusCode: response.status}))

  // Since `fetch` is asynchronous, must return an explicit `true`
  return true;
}

chrome.runtime.onMessage.addListener(handleMessages);

// From the sender's context...
const {statusCode} = await chrome.runtime.sendMessage('get-status');

इवेंट लिसनर को कॉल करने पर, sendResponse फ़ंक्शन को तीसरे पैरामीटर के तौर पर पास किया जाता है. यह एक ऐसा फ़ंक्शन है जिसे जवाब देने के लिए कॉल किया जा सकता है. डिफ़ॉल्ट रूप से, sendResponse कॉलबैक को सिंक्रोनस तरीके से कॉल किया जाना चाहिए.

अगर आपने बिना किसी पैरामीटर के sendResponse को कॉल किया है, तो null को जवाब के तौर पर भेजा जाता है.

एसिंक्रोनस तरीके से जवाब भेजने के लिए, आपके पास दो विकल्प हैं: true को वापस भेजना या प्रॉमिस को वापस भेजना.

लौटाएं true

sendResponse() का इस्तेमाल करके एसिंक्रोनस तरीके से जवाब देने के लिए, इवेंट लिसनर से लिटरल true (सिर्फ़ ट्रुथी वैल्यू नहीं) दिखाएं. ऐसा करने से, मैसेज चैनल तब तक खुला रहेगा, जब तक sendResponse को कॉल नहीं किया जाता. इससे आपको बाद में इसे कॉल करने की सुविधा मिलती है.

वादा वापस करना

Chrome 144 से, मैसेज लिसनर से प्रॉमिस वापस किया जा सकता है, ताकि एसिंक्रोनस तरीके से जवाब दिया जा सके. अगर प्रॉमिस पूरा हो जाता है, तो उसकी वैल्यू को जवाब के तौर पर भेजा जाता है.

अगर प्रॉमिस अस्वीकार कर दिया जाता है, तो भेजने वाले का sendMessage() कॉल अस्वीकार कर दिया जाएगा. साथ ही, गड़बड़ी का मैसेज भी दिखेगा. ज़्यादा जानकारी और उदाहरणों के लिए, गड़बड़ी ठीक करना सेक्शन देखें.

यहां एक उदाहरण दिया गया है, जिसमें ऐसे प्रॉमिस को वापस लाने का तरीका बताया गया है जिसे पूरा किया जा सकता है या अस्वीकार किया जा सकता है:

// Event listener
function handleMessages(message, sender, sendResponse) {
  // Return a promise that wraps fetch
  // If the response is OK, resolve with the status. If it's not OK then reject
  // with the network error that prevents the fetch from completing.
  return new Promise((resolve, reject) => {
    fetch('https://example.com')
      .then(response => {
        if (!response.ok) {
          reject(response);
        } else {
          resolve(response.status);
        }
      })
      .catch(error => {
        reject(error);
      });
  });
}
chrome.runtime.onMessage.addListener(handleMessages);

प्रॉमिस वापस करने के लिए, लिसनर को async के तौर पर भी एलान किया जा सकता है:

chrome.runtime.onMessage.addListener(async function(message, sender) {
  const response = await fetch('https://example.com');
  if (!response.ok) {
    // rejects the promise returned by `async function`.
    throw new Error(`Fetch failed: ${response.status}`);
  }
  // resolves the promise returned by `async function`.
  return {statusCode: response.status};
});

प्रॉमिस को वापस करना: async फ़ंक्शन की गॉटचा

ध्यान रखें कि लिसनर के तौर पर काम करने वाला async फ़ंक्शन, हमेशा प्रॉमिस देता है. भले ही, उसमें return स्टेटमेंट न हो. अगर async लिसनर कोई वैल्यू नहीं देता है, तो इसका प्रॉमिस अपने-आप undefined पर सेट हो जाता है. साथ ही, null को ईमेल भेजने वाले व्यक्ति को जवाब के तौर पर भेजा जाता है. एक से ज़्यादा लिसनर होने पर, इससे अनचाहा व्यवहार हो सकता है:

// content_script.js
function handleResponse(message) {
    // The first listener promise resolves to `undefined` before the second
    // listener can respond. When a listener responds with `undefined`, Chrome
    // sends null as the response.
    console.assert(message === null);
}
function notifyBackgroundPage() {
    const sending = chrome.runtime.sendMessage('test');
    sending.then(handleResponse);
}
notifyBackgroundPage();

// background.js
chrome.runtime.onMessage.addListener(async (message) => {
    // This just causes the function to pause for a millisecond, but the promise
    // is *not* returned from the listener so it doesn't act as a response.
    await new Promise(resolve => {
        setTimeout(resolve, 1, 'OK');
    });
   // `async` functions always return promises. So once we
   // reach here there is an implicit `return undefined;`. Chrome translates
   // `undefined` responses to `null`.
});

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  return new Promise((resolve) => {
    setTimeout(resolve, 1000, 'response');
  });
});

गड़बड़ी ठीक करना

Chrome 144 से, अगर कोई onMessage लिसनर कोई गड़बड़ी दिखाता है (सिंक्रोनस या एसिंक्रोनस तरीके से, प्रॉमिस को अस्वीकार करके), तो सेंडर में onMessage से मिला प्रॉमिस, गड़बड़ी के मैसेज के साथ अस्वीकार कर दिया जाएगा.sendMessage() ऐसा तब भी हो सकता है, जब कोई लिसनर ऐसा जवाब देने की कोशिश करता है जिसे TypeError को कैप्चर किए बिना JSON-सीरियलाइज़ नहीं किया जा सकता.

अगर कोई लिसनर ऐसा प्रॉमिस दिखाता है जिसे अस्वीकार कर दिया गया है, तो उसे Error इंस्टेंस के साथ अस्वीकार करना होगा, ताकि भेजने वाले को गड़बड़ी का वह मैसेज मिल सके. अगर प्रॉमिस को किसी दूसरी वैल्यू (जैसे कि null या undefined) के साथ अस्वीकार किया जाता है, तो sendMessage() को गड़बड़ी के सामान्य मैसेज के साथ अस्वीकार कर दिया जाएगा.

अगर onMessage के लिए एक से ज़्यादा लिसनर रजिस्टर किए गए हैं, तो सिर्फ़ पहले लिसनर के जवाब देने, अनुरोध अस्वीकार करने या गड़बड़ी होने पर, ईमेल भेजने वाले पर असर पड़ेगा. अन्य सभी लिसनर काम करेंगे, लेकिन उनके नतीजों को अनदेखा कर दिया जाएगा.

उदाहरण

अगर कोई लिसनर ऐसा प्रॉमिस वापस करता है जिसे अस्वीकार कर दिया गया है, तो sendMessage() को अस्वीकार कर दिया जाता है:

// sender.js
try {
  await chrome.runtime.sendMessage('test');
} catch (e) {
  console.log(e.message); // "some error"
}

// listener.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  return Promise.reject(new Error('some error'));
});

अगर लिसनर ऐसी वैल्यू के साथ जवाब देता है जिसे क्रम से नहीं लगाया जा सकता, तो sendMessage() को अस्वीकार कर दिया जाता है:

// sender.js
try {
  await chrome.runtime.sendMessage('test');
} catch (e) {
  console.log(e.message); // "Error: Could not serialize message."
}

// listener.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  sendResponse(() => {}); // Functions are not serializable
  return true; // Keep channel open for async sendResponse
});

अगर कोई लिसनर, किसी दूसरे लिसनर के जवाब देने से पहले सिंक्रोनस तरीके से गड़बड़ी करता है, तो लिसनर का sendMessage() प्रॉमिस अस्वीकार कर दिया जाता है:

// sender.js
try {
  await chrome.runtime.sendMessage('test');
} catch (e) {
  console.log(e.message); // "error!"
}

// listener.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  throw new Error('error!');
});

हालांकि, अगर कोई लिसनर किसी दूसरे लिसनर के गड़बड़ी का मैसेज देने से पहले जवाब देता है, तो sendMessage() सफल होता है:

// sender.js
const response = await chrome.runtime.sendMessage('test');
console.log(response); // "OK"

// listener.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  sendResponse('OK');
});
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  throw new Error('error!');
});

लंबे समय तक चलने वाले कनेक्शन

फिर से इस्तेमाल किया जा सकने वाला मैसेज पासिंग चैनल बनाने के लिए, इस फ़ंक्शन को कॉल करें:

  • runtime.connect() का इस्तेमाल, कॉन्टेंट स्क्रिप्ट से एक्सटेंशन पेज पर मैसेज भेजने के लिए किया जाता है
  • tabs.connect() का इस्तेमाल, एक्सटेंशन पेज से कॉन्टेंट स्क्रिप्ट तक मैसेज भेजने के लिए किया जाता है.

अलग-अलग तरह के कनेक्शन के बीच अंतर करने के लिए, name कुंजी के साथ options पैरामीटर पास करके, अपने चैनल का नाम दिया जा सकता है:

const port = chrome.runtime.connect({name: "example"});

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

कनेक्शन बनाते समय, हर एंड को runtime.Port ऑब्जेक्ट असाइन किया जाता है. इससे उस कनेक्शन के ज़रिए मैसेज भेजे और पाए जा सकते हैं.

कॉन्टेंट स्क्रिप्ट से कोई चैनल खोलने, मैसेज भेजने, और मैसेज सुनने के लिए, इस कोड का इस्तेमाल करें:

content-script.js:

const port = chrome.runtime.connect({name: "knockknock"});
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"});
  }
});
port.postMessage({joke: "Knock knock"});

एक्सटेंशन से कॉन्टेंट स्क्रिप्ट को अनुरोध भेजने के लिए, पिछले उदाहरण में runtime.connect() को tabs.connect() से बदलें.

कॉन्टेंट स्क्रिप्ट या एक्सटेंशन पेज के लिए, आने वाले कनेक्शन को हैंडल करने के लिए, runtime.onConnect इवेंट लिसनर सेट अप करें. जब आपके एक्सटेंशन का कोई दूसरा हिस्सा connect() को कॉल करता है, तो यह इवेंट और runtime.Port ऑब्जेक्ट चालू हो जाता है. आने वाले कनेक्शन के लिए जवाब देने वाला कोड ऐसा दिखता है:

service-worker.js:

chrome.runtime.onConnect.addListener(function(port) {
  if (port.name !== "knockknock") {
    return;
  }
  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."});
    }
  });
});

एपिसोड क्रम से लगाने की सेटिंग

Chrome में, मैसेज पास करने वाले एपीआई JSON serialization का इस्तेमाल करते हैं. खास तौर पर, यह अन्य ब्राउज़र से अलग है. अन्य ब्राउज़र, स्ट्रक्चर्ड क्लोन एल्गोरिदम के साथ एक ही एपीआई लागू करते हैं.

इसका मतलब है कि मैसेज (और पाने वालों से मिले जवाब) में कोई भी JSON.stringify() मान्य वैल्यू हो सकती है. अन्य वैल्यू को सीरियलाइज़ की जा सकने वाली वैल्यू में बदल दिया जाएगा. खास तौर पर, undefined को null के तौर पर सीरियलाइज़ किया जाएगा;

ईमेल के साइज़ की सीमाएं

मैसेज का साइज़ ज़्यादा से ज़्यादा 64 MiB हो सकता है.

पोर्ट करने की अवधि

पोर्ट को एक्सटेंशन के अलग-अलग हिस्सों के बीच, दो-तरफ़ा कम्यूनिकेशन के तरीके के तौर पर डिज़ाइन किया गया है. जब एक्सटेंशन का कोई हिस्सा 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 तरीकों का इस्तेमाल करें. यहां हर एक का उदाहरण दिया गया है:

service-worker.js

// For a single request:
chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.id !== allowlistedExtension) {
      return; // don't allow this extension access
    }
    if (request.getTargetData) {
      sendResponse({ targetData: targetData });
    } else if (request.activateLasers) {
      const 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.
  });
});

किसी दूसरे एक्सटेंशन को मैसेज भेजने के लिए, उस एक्सटेंशन का आईडी पास करें जिससे आपको कम्यूनिकेट करना है. इसके लिए, यह तरीका अपनाएं:

service-worker.js

// The ID of the extension we want to talk to.
const laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// For a minimal request:
chrome.runtime.sendMessage(laserExtensionId, {getTargetData: true},
  function(response) {
    if (targetInRange(response.targetData))
      chrome.runtime.sendMessage(laserExtensionId, {activateLasers: true});
  }
);

// For a long-lived connection:
const port = chrome.runtime.connect(laserExtensionId);
port.postMessage(...);

वेब पेजों से मैसेज भेजना

एक्सटेंशन, वेब पेजों से मैसेज पा सकते हैं और उनका जवाब दे सकते हैं. किसी वेब पेज से एक्सटेंशन को मैसेज भेजने के लिए, manifest.json में यह तय करें कि आपको किन वेबसाइटों से मैसेज पाने की अनुमति देनी है. इसके लिए, "externally_connectable" मेनिफ़ेस्ट कुंजी का इस्तेमाल करें. उदाहरण के लिए:

manifest.json

"externally_connectable": {
  "matches": ["https://*.example.com/*"]
}

इससे, मैसेजिंग एपीआई को उन सभी पेजों के लिए उपलब्ध कराया जाता है जो आपके तय किए गए यूआरएल पैटर्न से मेल खाते हैं. यूआरएल पैटर्न में कम से कम एक सेकंड-लेवल डोमेन होना चाहिए. इसका मतलब है कि "*", "*.com", "*.co.uk", और "*.appspot.com" जैसे होस्टनेम पैटर्न इस्तेमाल नहीं किए जा सकते. सभी डोमेन को ऐक्सेस करने के लिए, <all_urls> का इस्तेमाल किया जा सकता है.

किसी एक्सटेंशन को मैसेज भेजने के लिए, runtime.sendMessage() या runtime.connect() एपीआई का इस्तेमाल करें. उदाहरण के लिए:

webpage.js

// The ID of the extension we want to talk to.
const editorExtensionId = 'abcdefghijklmnoabcdefhijklmnoabc';

// Check if extension is installed
if (chrome && chrome.runtime) {
  // Make a request:
  chrome.runtime.sendMessage(
    editorExtensionId,
    {
      openUrlInEditor: url
    },
    (response) => {
      if (!response.success) handleError(url);
    }
  );
}

अपने एक्सटेंशन से, वेब पेजों के मैसेज सुनो. इसके लिए, runtime.onMessageExternal या runtime.onConnectExternal एपीआई का इस्तेमाल करो. ऐसा क्रॉस-एक्सटेंशन मैसेजिंग में किया जाता है. यहां एक उदाहरण दिया गया है:

service-worker.js

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);
  });

एक्सटेंशन से वेब पेज पर मैसेज नहीं भेजा जा सकता.

नेटिव मैसेज सेवा

एक्सटेंशन, नेटिव ऐप्लिकेशन के साथ मैसेज शेयर कर सकते हैं. ये ऐप्लिकेशन, नेटिव मैसेजिंग होस्ट के तौर पर रजिस्टर होते हैं. इस सुविधा के बारे में ज़्यादा जानने के लिए, नेटिव मैसेजिंग लेख पढ़ें.

सुरक्षा से जुड़ी बातें

यहां मैसेजिंग से जुड़ी सुरक्षा के बारे में कुछ बातें बताई गई हैं.

कॉन्टेंट स्क्रिप्ट पर कम भरोसा किया जा सकता है

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

क्रॉस-साइट स्क्रिप्टिंग

पक्का करें कि आपकी स्क्रिप्ट, क्रॉस-साइट स्क्रिप्टिंग से सुरक्षित हों. जब आपको किसी ऐसे सोर्स से डेटा मिलता है जिस पर भरोसा नहीं किया जा सकता, तो इस बात का ध्यान रखें कि उसे एचटीएमएल के तौर पर न समझा जाए. साथ ही, उसका इस्तेमाल इस तरह से न किया जाए कि अनचाहे कोड को चलने की अनुमति मिल जाए. जैसे, उपयोगकर्ता का इनपुट, कॉन्टेंट स्क्रिप्ट के ज़रिए अन्य वेबसाइटें या कोई एपीआई.

ज़्यादा सुरक्षित तरीके

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

service-worker.js

chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // JSON.parse doesn't evaluate the attacker's scripts.
  const resp = JSON.parse(response.farewell);
});

service-worker.js

chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // innerText does not let the attacker inject HTML elements.
  document.getElementById("resp").innerText = response.farewell;
});
असुरक्षित तरीके

अपने एक्सटेंशन को कमज़ोर बनाने वाले इन तरीकों का इस्तेमाल न करें:

service-worker.js

chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // WARNING! Might be evaluating a malicious script!
  const resp = eval(`(${response.farewell})`);
});

service-worker.js

chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // WARNING! Might be injecting a malicious script!
  document.getElementById("resp").innerHTML = response.farewell;
});