বিষয়বস্তু স্ক্রিপ্ট

কন্টেন্ট স্ক্রিপ্ট হলো এমন ফাইল যা ওয়েব পৃষ্ঠার প্রেক্ষাপটে চলে। স্ট্যান্ডার্ড ডকুমেন্ট অবজেক্ট মডেল (DOM) ব্যবহার করে, তারা ব্রাউজার যে ওয়েব পৃষ্ঠাগুলি পরিদর্শন করে তার বিশদ বিবরণ পড়তে, সেগুলিতে পরিবর্তন করতে এবং তাদের মূল এক্সটেনশনে তথ্য প্রেরণ করতে সক্ষম হয়।

কন্টেন্ট স্ক্রিপ্টের ক্ষমতা বুঝুন

কন্টেন্ট স্ক্রিপ্টগুলি নিম্নলিখিত এক্সটেনশন API গুলি সরাসরি অ্যাক্সেস করতে পারে:

কন্টেন্ট স্ক্রিপ্টগুলি সরাসরি অন্যান্য API গুলিতে অ্যাক্সেস করতে অক্ষম। তবে তারা আপনার এক্সটেনশনের অন্যান্য অংশের সাথে বার্তা বিনিময় করে পরোক্ষভাবে সেগুলিতে অ্যাক্সেস করতে পারে।

আপনি fetch() এর মতো API ব্যবহার করে একটি কন্টেন্ট স্ক্রিপ্ট থেকে আপনার এক্সটেনশনের অন্যান্য ফাইলগুলিও অ্যাক্সেস করতে পারেন। এটি করার জন্য, আপনাকে সেগুলিকে ওয়েব-অ্যাক্সেসযোগ্য রিসোর্স হিসাবে ঘোষণা করতে হবে। মনে রাখবেন যে এটি একই সাইটে চলমান যেকোনো প্রথম-পক্ষ বা তৃতীয়-পক্ষের স্ক্রিপ্টগুলিতেও রিসোর্সগুলি প্রকাশ করে।

বিচ্ছিন্ন পৃথিবীতে কাজ করুন

কন্টেন্ট স্ক্রিপ্টগুলি একটি বিচ্ছিন্ন জগতে বাস করে, যা একটি কন্টেন্ট স্ক্রিপ্টকে পৃষ্ঠা বা অন্যান্য এক্সটেনশনের কন্টেন্ট স্ক্রিপ্টের সাথে বিরোধ না করেই তার জাভাস্ক্রিপ্ট পরিবেশে পরিবর্তন করতে দেয়।

একটি এক্সটেনশন নিম্নলিখিত উদাহরণের মতো কোড সহ একটি ওয়েব পৃষ্ঠায় চলতে পারে।

ওয়েবপেজ.এইচটিএমএল

<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>

সেই এক্সটেনশনটি ইনজেক্ট স্ক্রিপ্ট বিভাগে বর্ণিত কৌশলগুলির একটি ব্যবহার করে নিম্নলিখিত কন্টেন্ট স্ক্রিপ্টটি ইনজেক্ট করতে পারে।

কন্টেন্ট-স্ক্রিপ্ট.জেএস

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 ফাইল, CSS ফাইল, অথবা উভয়ই অন্তর্ভুক্ত থাকতে পারে। সমস্ত স্বয়ংক্রিয়ভাবে চালিত কন্টেন্ট স্ক্রিপ্টগুলিকে মিলের ধরণ নির্দিষ্ট করতে হবে।

ম্যানিফেস্ট.জেসন

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

নাম আদর্শ বিবরণ
matches স্ট্রিং অ্যারে প্রয়োজনীয়। এই কন্টেন্ট স্ক্রিপ্টটি কোন পৃষ্ঠাগুলিতে ইনজেক্ট করা হবে তা নির্দিষ্ট করে। এই স্ট্রিংগুলির সিনট্যাক্স সম্পর্কে বিস্তারিত জানতে "ম্যাচ প্যাটার্নস" এবং URLগুলি কীভাবে বাদ দিতে হয় সে সম্পর্কে তথ্যের জন্য "ম্যাচ প্যাটার্নস এবং গ্লোবস" দেখুন।
css স্ট্রিং অ্যারে ঐচ্ছিক। মিলিত পৃষ্ঠাগুলিতে ইনজেক্ট করার জন্য CSS ফাইলের তালিকা। পৃষ্ঠার জন্য কোনও DOM তৈরি বা প্রদর্শিত হওয়ার আগে, এই অ্যারেতে প্রদর্শিত ক্রম অনুসারে এগুলি ইনজেক্ট করা হয়।
js স্ট্রিং অ্যারে ঐচ্ছিক। মিলে যাওয়া পৃষ্ঠাগুলিতে জাভাস্ক্রিপ্ট ফাইলগুলির তালিকা। এই অ্যারেতে প্রদর্শিত ক্রম অনুসারে ফাইলগুলি ইনজেক্ট করা হয়। এই তালিকার প্রতিটি স্ট্রিংয়ে এক্সটেনশনের রুট ডিরেক্টরিতে একটি রিসোর্সের একটি আপেক্ষিক পথ থাকতে হবে। লিডিং স্ল্যাশ (`/`) স্বয়ংক্রিয়ভাবে ছাঁটাই করা হয়।
run_at রানঅ্যাট ঐচ্ছিক। পৃষ্ঠায় স্ক্রিপ্টটি কখন ইনজেক্ট করা উচিত তা নির্দিষ্ট করে। ডিফল্টরূপে document_idle থাকে।
match_about_blank বুলিয়ান ঐচ্ছিক। স্ক্রিপ্টটি কি about:blank ফ্রেমে প্রবেশ করানো উচিত যেখানে প্যারেন্ট বা ওপেনার ফ্রেম matches এ ঘোষিত প্যাটার্নগুলির একটির সাথে মেলে। ডিফল্টভাবে false হয়।
match_origin_as_fallback বুলিয়ান ঐচ্ছিক। স্ক্রিপ্টটি কি এমন ফ্রেমে ইনজেক্ট করবে যেগুলি একটি মিলিত উৎস দ্বারা তৈরি করা হয়েছে, কিন্তু যার URL বা উৎস সরাসরি প্যাটার্নের সাথে মেলে না। এর মধ্যে বিভিন্ন স্কিম সহ ফ্রেম অন্তর্ভুক্ত রয়েছে, যেমন about: , data: , blob: , এবং filesystem: সম্পর্কিত ফ্রেমে ইনজেক্ট করা দেখুন।
world এক্সিকিউশনওয়ার্ল্ড ঐচ্ছিক। স্ক্রিপ্ট চালানোর জন্য জাভাস্ক্রিপ্ট জগৎ। ডিফল্টভাবে ISOLATED । আরও দেখুন Work in isolated worlds

ডকুমেন্ট লাইফসাইকেলের একটি নির্দিষ্ট পর্যায়ে , ম্যানিফেস্টে স্ট্যাটিক্যালি ঘোষিত কন্টেন্ট স্ক্রিপ্টগুলি প্রথমে ইনজেক্ট করা হয়, অন্য কোনও উপায়ে কন্টেন্ট স্ক্রিপ্টগুলি নিবন্ধিত হওয়ার আগে। ম্যানিফেস্টে যে ক্রমে নির্দিষ্ট করা আছে সেভাবেই এগুলি ইনজেক্ট করা হয়।

গতিশীল ঘোষণা দিয়ে ইনজেক্ট করুন

যখন কন্টেন্ট স্ক্রিপ্টের মিলের ধরণগুলি সুপরিচিত না থাকে অথবা যখন কন্টেন্ট স্ক্রিপ্টগুলি সর্বদা পরিচিত হোস্টে ইনজেক্ট করা উচিত নয়, তখন ডায়নামিক কন্টেন্ট স্ক্রিপ্টগুলি কার্যকর।

Chrome 96-এ প্রবর্তিত, গতিশীল ঘোষণাগুলি স্ট্যাটিক ঘোষণার অনুরূপ, তবে কন্টেন্ট স্ক্রিপ্ট অবজেক্টটি manifest.json- এর পরিবর্তে chrome.scripting namespace-এর পদ্ধতি ব্যবহার করে Chrome-এ নিবন্ধিত হয়। স্ক্রিপ্টিং API এক্সটেনশন ডেভেলপারদের এটি করার অনুমতি দেয়:

স্ট্যাটিক ডিক্লারেশনের মতো, ডাইনামিক ডিক্লারেশনে জাভাস্ক্রিপ্ট ফাইল, সিএসএস ফাইল, অথবা উভয়ই অন্তর্ভুক্ত থাকতে পারে।

সার্ভিস-ওয়ার্কার.জেএস

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

সার্ভিস-ওয়ার্কার.জেএস

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

সার্ভিস-ওয়ার্কার.জেএস

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

সার্ভিস-ওয়ার্কার.জেএস

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

প্রোগ্রাম্যাটিকভাবে ইনজেক্ট করুন

ইভেন্টের প্রতিক্রিয়ায় বা নির্দিষ্ট অনুষ্ঠানে চালানোর প্রয়োজন এমন কন্টেন্ট স্ক্রিপ্টগুলির জন্য প্রোগ্রাম্যাটিক ইনজেকশন ব্যবহার করুন।

প্রোগ্রাম্যাটিকভাবে কোনও কন্টেন্ট স্ক্রিপ্ট ইনজেক্ট করার জন্য, আপনার এক্সটেনশনের যে পৃষ্ঠায় স্ক্রিপ্ট ইনজেক্ট করার চেষ্টা করা হচ্ছে তার জন্য হোস্ট অনুমতি প্রয়োজন। হোস্ট অনুমতিগুলি হয় আপনার এক্সটেনশনের ম্যানিফেস্টের অংশ হিসাবে অনুরোধ করে অথবা অস্থায়ীভাবে "activeTab" ব্যবহার করে মঞ্জুর করা যেতে পারে।

নিচে একটি activeTab-ভিত্তিক এক্সটেনশনের বিভিন্ন সংস্করণ দেওয়া হল।

ম্যানিফেস্ট.জেসন:

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

কন্টেন্ট স্ক্রিপ্টগুলি ফাইল হিসাবে ইনজেক্ট করা যেতে পারে।

কন্টেন্ট-স্ক্রিপ্ট.জেএস


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 নিক্ষেপ করবে।

ফাংশন হিসেবে ইনজেক্ট করার সময়, আপনি ফাংশনে আর্গুমেন্টও পাস করতে পারেন।

সার্ভিস-ওয়ার্কার.জেএস

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 পরে প্রয়োগ করা হয়েছে যাতে শুধুমাত্র সেই URL গুলি অন্তর্ভুক্ত করা হয় যা এই গ্লোবের সাথে মেলে। এটি @include Greasemonkey কীওয়ার্ড অনুকরণ করার উদ্দেশ্যে করা হয়েছে।
exclude_globs স্ট্রিং অ্যারে ঐচ্ছিক। এই গ্লোবের সাথে মেলে এমন URL গুলি বাদ দেওয়ার জন্য matches পরে প্রয়োগ করা হয়েছে। @exclude Greasemonkey কীওয়ার্ড অনুকরণ করার উদ্দেশ্যে।

নিম্নলিখিত দুটি সত্য হলে কন্টেন্ট স্ক্রিপ্টটি একটি পৃষ্ঠায় ইনজেক্ট করা হবে:

  • এর URL যেকোনো matches প্যাটার্ন এবং যেকোনো include_globs প্যাটার্নের সাথে মেলে।
  • URLটি exclude_matches বা exclude_globs প্যাটার্নের সাথেও মেলে না। যেহেতু matches প্রপার্টিটি প্রয়োজন, exclude_matches , include_globs , এবং exclude_globs শুধুমাত্র কোন পৃষ্ঠাগুলি প্রভাবিত হবে তা সীমাবদ্ধ করতে ব্যবহার করা যেতে পারে।

নিম্নলিখিত এক্সটেনশনটি কন্টেন্ট স্ক্রিপ্টটি https://www.nytimes.com/health এ প্রবেশ করায় কিন্তু https://www.nytimes.com/business এ নয়।

ম্যানিফেস্ট.জেসন

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

সার্ভিস-ওয়ার্কার.জেএস

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

গ্লোব প্রোপার্টি ম্যাচ প্যাটার্নের চেয়ে ভিন্ন, আরও নমনীয় সিনট্যাক্স অনুসরণ করে। গ্রহণযোগ্য গ্লোব স্ট্রিং হল এমন URL যেখানে "ওয়াইল্ডকার্ড" তারকাচিহ্ন এবং প্রশ্ন চিহ্ন থাকতে পারে। তারকাচিহ্ন ( * ) যেকোনো দৈর্ঘ্যের যেকোনো স্ট্রিং এর সাথে মেলে, খালি স্ট্রিং সহ, যখন প্রশ্ন চিহ্ন ( ? ) যেকোনো একক অক্ষরের সাথে মেলে।

উদাহরণস্বরূপ, গ্লোব 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 তে নয়:

ম্যানিফেস্ট.জেসন

{
  "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 তে নয়:

ম্যানিফেস্ট.জেসন

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

সঠিক পরিধি অর্জনের জন্য একটি, সমস্ত, অথবা এর মধ্যে কিছু অন্তর্ভুক্ত করা যেতে পারে।

ম্যানিফেস্ট.জেসন

{
  "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 ফিল্ড নিয়ন্ত্রণ করে। পছন্দের এবং ডিফল্ট মান হল "document_idle" । অন্যান্য সম্ভাব্য মানের জন্য RunAt টাইপটি দেখুন।

ম্যানিফেস্ট.জেসন

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "run_at": "document_idle",
      "js": ["contentScript.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 এর পরে চালানোর প্রয়োজন হয়, তাহলে এক্সটেনশনটি document.readyState প্রোপার্টি ব্যবহার করে onload ইতিমধ্যেই চালু হয়েছে কিনা তা পরীক্ষা করতে পারে।
document_start স্ট্রিং css থেকে যেকোনো ফাইলের পরে স্ক্রিপ্টগুলি ইনজেক্ট করা হয়, কিন্তু অন্য কোনও DOM তৈরি হওয়ার আগে বা অন্য কোনও স্ক্রিপ্ট চালানোর আগে।
document_end স্ট্রিং DOM সম্পূর্ণ হওয়ার পরপরই, কিন্তু ছবি এবং ফ্রেমের মতো সাবরিসোর্স লোড হওয়ার আগেই স্ক্রিপ্টগুলি ইনজেক্ট করা হয়।

ফ্রেম নির্দিষ্ট করুন

ম্যানিফেস্টে নির্দিষ্ট করা ঘোষণামূলক কন্টেন্ট স্ক্রিপ্টের জন্য, "all_frames" ফিল্ড এক্সটেনশনটিকে নির্দিষ্ট করার অনুমতি দেয় যে জাভাস্ক্রিপ্ট এবং CSS ফাইলগুলি নির্দিষ্ট URL প্রয়োজনীয়তার সাথে মিলে যাওয়া সমস্ত ফ্রেমে ইনজেক্ট করা উচিত নাকি শুধুমাত্র একটি ট্যাবের শীর্ষতম ফ্রেমে ইনজেক্ট করা উচিত:

ম্যানিফেস্ট.জেসন

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

chrome.scripting.registerContentScripts(...) ব্যবহার করে প্রোগ্রাম্যাটিকভাবে কন্টেন্ট স্ক্রিপ্ট নিবন্ধন করার সময়, allFrames প্যারামিটার ব্যবহার করে নির্দিষ্ট URL প্রয়োজনীয়তার সাথে মেলে এমন সমস্ত ফ্রেমে কন্টেন্ট স্ক্রিপ্ট ইনজেক্ট করা উচিত কিনা তা নির্দিষ্ট করা যেতে পারে, নাকি শুধুমাত্র একটি ট্যাবের সর্বোচ্চ ফ্রেমে। এটি শুধুমাত্র tabId এর সাথে ব্যবহার করা যেতে পারে, এবং frameIds বা documentIds নির্দিষ্ট করা থাকলে ব্যবহার করা যাবে না:

সার্ভিস-ওয়ার্কার.জেএস

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

এক্সটেনশনগুলি এমন ফ্রেমে স্ক্রিপ্ট চালাতে চাইতে পারে যা একটি মিলে যাওয়া ফ্রেমের সাথে সম্পর্কিত, কিন্তু নিজেরাই মেলে না। এই ক্ষেত্রে একটি সাধারণ পরিস্থিতি হল এমন ফ্রেমগুলির জন্য যেখানে URL গুলি একটি মিলে যাওয়া ফ্রেম দ্বারা তৈরি করা হয়েছে, কিন্তু যাদের URL গুলি স্ক্রিপ্টের নির্দিষ্ট প্যাটার্নের সাথে মেলে না।

এটি তখনই ঘটে যখন কোনও এক্সটেনশন এমন ফ্রেমে প্রবেশ করাতে চায় যেখানে about: , data: , blob: , এবং filesystem: স্কিম থাকে। এই ক্ষেত্রে, URLটি কন্টেন্ট স্ক্রিপ্টের প্যাটার্নের সাথে মেলে না (এবং, about: এবং data: এর ক্ষেত্রে, URL-এ একেবারেই প্যারেন্ট URL বা অরিজিন অন্তর্ভুক্ত করবেন না, যেমন about:blank অথবা data:text/html,<html>Hello, World!</html> )। তবে, এই ফ্রেমগুলি এখনও তৈরি ফ্রেমের সাথে যুক্ত হতে পারে।

এই ফ্রেমগুলিতে প্রবেশ করার জন্য, এক্সটেনশনগুলি ম্যানিফেস্টে একটি কন্টেন্ট স্ক্রিপ্ট স্পেসিফিকেশনে "match_origin_as_fallback" বৈশিষ্ট্য নির্দিষ্ট করতে পারে।

ম্যানিফেস্ট.জেসন

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

নির্দিষ্ট করে true তে সেট করা হলে, Chrome ফ্রেমের URL-এর পরিবর্তে ফ্রেমটি মিলছে কিনা তা নির্ধারণ করার জন্য ফ্রেমের ইনিশিয়েটারের উৎসের দিকে নজর দেবে। মনে রাখবেন যে এটি লক্ষ্য ফ্রেমের উৎসের চেয়েও আলাদা হতে পারে (যেমন, data: URL-এর একটি নাল উৎস থাকে)।

ফ্রেমের ইনিশিয়েটর হল সেই ফ্রেম যা টার্গেট ফ্রেম তৈরি বা নেভিগেট করেছে। যদিও এটি সাধারণত ডাইরেক্ট প্যারেন্ট বা ওপেনার হয়, এটি নাও হতে পারে (যেমন একটি ফ্রেম একটি আইফ্রেমের মধ্যে একটি আইফ্রেম নেভিগেট করার ক্ষেত্রে)।

যেহেতু এটি ইনিশিয়েটার ফ্রেমের উৎপত্তির তুলনা করে, তাই ইনিশিয়েটার ফ্রেমটি সেই উৎপত্তিস্থল থেকে যেকোনো পাথে থাকতে পারে। এই ইঙ্গিতটি স্পষ্ট করার জন্য, Chrome-এর জন্য "match_origin_as_fallback" true তে সেট করা যেকোনো কন্টেন্ট স্ক্রিপ্টের প্রয়োজন হয় যাতে * এর একটি পাথও নির্দিষ্ট করা যায়।

যখন "match_origin_as_fallback" এবং "match_about_blank" উভয়ই নির্দিষ্ট করা থাকে, তখন "match_origin_as_fallback" অগ্রাধিকার পায়।

এম্বেডিং পৃষ্ঠার সাথে যোগাযোগ

যদিও কন্টেন্ট স্ক্রিপ্টের এক্সিকিউশন এনভায়রনমেন্ট এবং সেগুলি হোস্ট করা পৃষ্ঠাগুলি একে অপরের থেকে বিচ্ছিন্ন, তারা পৃষ্ঠার DOM-এ অ্যাক্সেস ভাগ করে নেয়। যদি পৃষ্ঠাটি কন্টেন্ট স্ক্রিপ্টের সাথে যোগাযোগ করতে চায়, অথবা কন্টেন্ট স্ক্রিপ্টের মাধ্যমে এক্সটেনশনের সাথে যোগাযোগ করতে চায়, তাহলে তাকে অবশ্যই শেয়ার করা DOM-এর মাধ্যমে তা করতে হবে।

window.postMessage() ব্যবহার করে একটি উদাহরণ সম্পন্ন করা যেতে পারে:

কন্টেন্ট-স্ক্রিপ্ট.জেএস

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

উদাহরণ.জেএস

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

এক্সটেনশনবিহীন পৃষ্ঠা, example.html, নিজের কাছে বার্তা পোস্ট করে। এই বার্তাটি কন্টেন্ট স্ক্রিপ্ট দ্বারা আটকানো হয় এবং পরিদর্শন করা হয় এবং তারপর এক্সটেনশন প্রক্রিয়ায় পোস্ট করা হয়। এইভাবে, পৃষ্ঠাটি এক্সটেনশন প্রক্রিয়ার সাথে যোগাযোগের একটি লাইন স্থাপন করে। একই উপায়ে বিপরীতটি সম্ভব।

এক্সটেনশন ফাইল অ্যাক্সেস করুন

একটি কন্টেন্ট স্ক্রিপ্ট থেকে একটি এক্সটেনশন ফাইল অ্যাক্সেস করতে, আপনি chrome.runtime.getURL() এ কল করে আপনার এক্সটেনশন অ্যাসেটের সম্পূর্ণ URL পেতে পারেন যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে ( content.js ):

কন্টেন্ট-স্ক্রিপ্ট.জেএস

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

CSS ফাইলে ফন্ট বা ছবি ব্যবহার করার জন্য, আপনি @@extension_id ব্যবহার করে একটি URL তৈরি করতে পারেন যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে ( 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 ফাইলে সমস্ত সম্পদকে ওয়েব অ্যাক্সেসযোগ্য সম্পদ হিসেবে ঘোষণা করতে হবে:

ম্যানিফেস্ট.জেসন

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

কন্টেন্ট নিরাপত্তা নীতি

বিচ্ছিন্ন জগতে চলমান কন্টেন্ট স্ক্রিপ্টগুলির নিম্নলিখিত কন্টেন্ট সিকিউরিটি পলিসি (CSP) রয়েছে:

script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' chrome-extension://abcdefghijklmopqrstuvwxyz/; object-src 'self';

অন্যান্য এক্সটেনশন প্রসঙ্গে প্রযোজ্য বিধিনিষেধের মতো, এটি eval() ব্যবহার এবং বহিরাগত স্ক্রিপ্ট লোড করা থেকে বিরত রাখে।

আনপ্যাকড এক্সটেনশনের জন্য, CSP-তে localhostও অন্তর্ভুক্ত থাকে:

script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:* chrome-extension://abcdefghijklmopqrstuvwxyz/; object-src 'self';

যখন একটি কন্টেন্ট স্ক্রিপ্ট মূল জগতে প্রবেশ করানো হয়, তখন পৃষ্ঠার CSP প্রযোজ্য হয়।

নিরাপদে থাকুন

বিচ্ছিন্ন জগৎ সুরক্ষার একটি স্তর প্রদান করলেও, কন্টেন্ট স্ক্রিপ্ট ব্যবহার করলে এক্সটেনশন এবং ওয়েব পৃষ্ঠায় দুর্বলতা তৈরি হতে পারে। যদি কন্টেন্ট স্ক্রিপ্টটি একটি পৃথক ওয়েবসাইট থেকে কন্টেন্ট গ্রহণ করে, যেমন fetch() কল করে, তাহলে ক্রস-সাইট স্ক্রিপ্টিং আক্রমণের বিরুদ্ধে কন্টেন্ট ফিল্টার করার আগে সতর্ক থাকুন। "ম্যান-ইন-দ্য-মিডল" আক্রমণ এড়াতে শুধুমাত্র HTTPS এর মাধ্যমে যোগাযোগ করুন।

ক্ষতিকারক ওয়েব পৃষ্ঠাগুলির জন্য ফিল্টার করতে ভুলবেন না। উদাহরণস্বরূপ, নিম্নলিখিত প্যাটার্নগুলি বিপজ্জনক এবং ম্যানিফেস্ট V3 তে অনুমোদিত নয়:

করো না

কন্টেন্ট-স্ক্রিপ্ট.জেএস

const data = document.getElementById("json-data");
// WARNING! Might be evaluating an evil script!
const parsed = eval("(" + data + ")");
করো না

কন্টেন্ট-স্ক্রিপ্ট.জেএস

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

পরিবর্তে, এমন নিরাপদ API পছন্দ করুন যা স্ক্রিপ্ট চালায় না:

কর

কন্টেন্ট-স্ক্রিপ্ট.জেএস

const data = document.getElementById("json-data")
// JSON.parse does not evaluate the attacker's scripts.
const parsed = JSON.parse(data);
কর

কন্টেন্ট-স্ক্রিপ্ট.জেএস

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