النصوص البرمجية للمحتوى

النصوص البرمجية للمحتوى هي ملفات يتم تشغيلها في سياق صفحات الويب. باستخدام نموذج كائن المستند (DOM) العادي، يمكنها قراءة تفاصيل صفحات الويب التي يزورها المتصفّح وإجراء تغييرات عليها ونقل المعلومات إلى الإضافة الرئيسية.

التعرّف على إمكانات النصوص البرمجية للمحتوى

يمكن للنصوص البرمجية للمحتوى الوصول مباشرةً إلى واجهات برمجة التطبيقات التالية للإضافة:

لا يمكن للنصوص البرمجية للمحتوى الوصول مباشرةً إلى واجهات برمجة التطبيقات الأخرى. ولكن يمكنها الوصول إليها بشكل غير مباشر من خلال تبادل الرسائل مع أجزاء أخرى من الإضافة.

يمكنك أيضًا الوصول إلى ملفات أخرى في الإضافة من نص برمجي للمحتوى، باستخدام واجهات برمجة التطبيقات مثل 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 أو ملفات CSS أو كليهما. يجب أن تحدّد جميع النصوص البرمجية للمحتوى التي يتم تشغيلها تلقائيًا أنماط المطابقة .

manifest.json

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

الاسم النوع الوصف
matches مجموعة من السلاسل مطلوبة. تحدّد الصفحات التي سيتم إدخال هذا النص البرمجي للمحتوى فيها. اطّلِع على أنماط المطابقة للحصول على تفاصيل حول بنية هذه السلاسل وعلى أنماط المطابقة والرموز العامة للحصول على معلومات حول كيفية استبعاد عناوين URL.
css مجموعة من السلاسل اختياري. قائمة بملفات CSS التي سيتم إدخالها في الصفحات المطابقة. يتم إدخال هذه الملفات بالترتيب الذي تظهر به في هذه المجموعة، قبل إنشاء أي نموذج كائن مستند (DOM) أو عرضه للصفحة.
js مجموعة من السلاسل اختياري. قائمة بملفات JavaScript التي سيتم إدخالها في الصفحات المطابقة. يتم إدخال الملفات بالترتيب الذي تظهر به في هذه المجموعة. يجب أن تحتوي كل سلسلة في هذه القائمة على مسار نسبي إلى أحد الموارد في الدليل الجذري للإضافة. تتم إزالة الشرطات المائلة (`/`) في بداية المسار تلقائيًا.
run_at RunAt اختياري. تحدّد هذه السمة الوقت الذي يجب فيه إدخال النص البرمجي في الصفحة. القيمة التلقائية هي document_idle.
match_about_blank قيمة منطقية اختياري. تحدّد هذه السمة ما إذا كان يجب إدخال النص البرمجي في إطار about:blank يتطابق فيه الإطار الرئيسي أو الإطار الذي تم فتحه مع أحد الأنماط المُعلَنة في matches. القيمة التلقائية هي "خطأ".
match_origin_as_fallback قيمة منطقية اختياري. تحدّد هذه السمة ما إذا كان يجب إدخال النص البرمجي في الإطارات التي تم إنشاؤها بواسطة مصدر مطابق، ولكن قد لا يتطابق عنوان URL أو المصدر الخاص بها مباشرةً مع النمط. ويشمل ذلك الإطارات التي تتضمّن مخططات مختلفة، مثل about:، وdata:، وblob:، و filesystem:. اطّلِع أيضًا على إدخال النصوص البرمجية في الإطارات ذات الصلة.
world ExecutionWorld اختياري. تحدّد هذه السمة بيئة JavaScript التي سيتم تنفيذ النص البرمجي فيها. القيمة التلقائية هي ISOLATED. اطّلِع أيضًا على العمل في بيئات معزولة.

ضمن مرحلة معيّنة من مراحل دورة حياة المستند، تكون النصوص البرمجية للمحتوى التي تم تعريفها بشكل ثابت في ملف البيان هي أول النصوص التي يتم إدخالها، قبل النصوص البرمجية للمحتوى التي تم تسجيلها بأي طريقة أخرى. ويتم إدخالها بالترتيب الذي تم تحديدها به في ملف البيان.

الإدخال باستخدام التعريفات الديناميكية

تكون النصوص البرمجية للمحتوى الديناميكية مفيدة عندما لا تكون أنماط المطابقة للنصوص البرمجية للمحتوى معروفة جيدًا أو عندما لا يجب إدخال النصوص البرمجية للمحتوى دائمًا على المضيفين المعروفين.

تم تقديم التعريفات الديناميكية في Chrome 96، وهي مشابهة لـ التعريفات الثابتة، ولكن يتم تسجيل عنصر النص البرمجي للمحتوى في Chrome باستخدام طرق في مساحة الاسم chrome.scripting بدلاً من manifest.json. تسمح Scripting API أيضًا لمطوّري الإضافات بما يلي:

على غرار التعريفات الثابتة، يمكن أن تتضمّن التعريفات الديناميكية ملفات JavaScript أو ملفات CSS أو كليهما.

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 لتضمين عناوين URL التي تتطابق أيضًا مع هذا الرمز العام فقط. يهدف ذلك إلى محاكاة الكلمة الرئيسية @include Greasemonkey.
exclude_globs مجموعة من السلاسل اختياري. يتم تطبيق هذه السمة بعد matches لاستبعاد عناوين URL التي تتطابق مع هذا الرمز العام. يهدف ذلك إلى محاكاة الكلمة الرئيسية @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 .

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" ],
}]);

تتّبع خصائص الرموز العامة بنية مختلفة وأكثر مرونةً من أنماط المطابقة. سلاسل الرموز العامة المقبولة هي عناوين 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:

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 property.
document_start سلسلة يتم إدخال النصوص البرمجية بعد أي ملفات من css، ولكن قبل إنشاء أي نموذج كائن مستند (DOM) آخر أو تشغيل أي نص برمجي آخر.
document_end سلسلة يتم إدخال النصوص البرمجية بعد اكتمال نموذج كائن المستند (DOM) مباشرةً، ولكن قبل تحميل الموارد الفرعية مثل الصور والإطارات.

تحديد الإطارات

بالنسبة إلى النصوص البرمجية للمحتوى الإعلانية المحدّدة في ملف البيان، يسمح الحقل "all_frames" للإضافة بتحديد ما إذا كان يجب إدخال ملفات JavaScript وCSS في جميع الإطارات التي تتطابق مع متطلبات عنوان URL المحدّدة أو في الإطار العلوي فقط في علامة تبويب:

manifest.json

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

عند تسجيل النصوص البرمجية للمحتوى آليًا باستخدام chrome.scripting.registerContentScripts(...)، يمكن استخدام المعلَمة allFrames لتحديد ما إذا كان يجب إدخال النص البرمجي للمحتوى في جميع الإطارات التي تتطابق مع متطلبات عنوان URL المحدّدة أو في الإطار العلوي فقط في علامة تبويب. لا يمكن استخدام هذه المعلَمة إلا مع `tabId`، ولا يمكن استخدامها إذا تم تحديد `frameIds` أو `documentIds`:

service-worker.js

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

قد تريد الإضافات تشغيل النصوص البرمجية في الإطارات ذات الصلة بإطار مطابق، ولكن لا تتطابق الإطارات نفسها. أحد السيناريوهات الشائعة التي يحدث فيها ذلك هو الإطارات التي تتضمّن عناوين URL تم إنشاؤها بواسطة إطار مطابق، ولكن لا تتطابق عناوين URL نفسها مع الأنماط المحدّدة للنص البرمجي.

يحدث ذلك عندما تريد إحدى الإضافات الإدخال في الإطارات التي تتضمّن عناوين URL لها المخططات about: وdata: وblob: وfilesystem:. في هذه الحالات، لن يتطابق عنوان URL مع نمط النص البرمجي للمحتوى (وفي حالة about: وdata:, لا يتضمّن عنوان URL حتى عنوان URL أو المصدر الرئيسي في عنوان URL على الإطلاق، كما في 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 إلى مصدر الإطار الذي بدأه لتحديد ما إذا كان الإطار مطابقًا، بدلاً من عنوان URL للإطار نفسه. يُرجى العِلم أنّ هذا قد يختلف أيضًا عن مصدر الإطار المستهدَف (على سبيل المثال، عناوين URL لـ data: لها مصدر فارغ).

الإطار الذي بدأ الإطار هو الإطار الذي أنشأ الإطار المستهدَف أو انتقل إليه. مع أنّ هذا الإطار هو عادةً الإطار الرئيسي المباشر أو الإطار الذي تم فتحه، قد لا يكون كذلك (كما في حالة إطار ينتقل إلى iframe داخل iframe).

بما أنّ هذا الإجراء يقارن مصدر الإطار الذي بدأ الإطار، يمكن أن يكون الإطار الذي بدأ الإطار على أي مسار من هذا المصدر. لتوضيح هذه النتيجة، يطلب Chrome من أي نصوص برمجية للمحتوى تم تحديدها باستخدام "match_origin_as_fallback" التي تم ضبطها على true أن تحدّد أيضًا مسارًا بقيمة *.

عند تحديد كل من "match_origin_as_fallback" و"match_about_blank"، تكون الأولوية لـ "match_origin_as_fallback".

التواصل مع الصفحة المضمِّنة

مع أنّ بيئات تنفيذ النصوص البرمجية للمحتوى والصفحات التي تستضيفها معزولة عن بعضها البعض، فإنّها تشترك في الوصول إلى نموذج كائن المستند (DOM) للصفحة. إذا أرادت الصفحة التواصل مع النص البرمجي للمحتوى أو مع الإضافة من خلال النص البرمجي للمحتوى، يجب أن يتم ذلك من خلال نموذج كائن المستند (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() للحصول على عنوان URL المطلق لمادة عرض الإضافة كما هو موضّح في المثال التالي (content.js):

content-script.js

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

لاستخدام الخطوط أو الصور في ملف CSS، يمكنك استخدام @@extension_id لإنشاء عنوان URL كما هو موضّح في المثال التالي (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 file:

manifest.json

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

سياسة أمان المحتوى

تتّبع النصوص البرمجية للمحتوى التي يتم تشغيلها في بيئات معزولة سياسة أمان المحتوى (CSP) التالية: سياسة أمان المحتوى (CSP):

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