نصوص برمجية للمحتوى هي ملفات يتم تشغيلها في سياق صفحات الويب. باستخدام نموذج ملف هِيأة المستند (DOM) العادي، يمكن لهذه الإضافات قراءة تفاصيل صفحات الويب التي يزورها المتصفّح وإجراء تعديلات عليها ونقل المعلومات إلى الإضافة الرئيسية.
فهم إمكانات نصوص المحتوى
يمكن لنصوص JavaScript للمحتوى الوصول إلى واجهات برمجة تطبيقات Chrome التي تستخدمها الإضافة الرئيسية من خلال تبادل الرسائل
مع الإضافة. ويمكنهم أيضًا الوصول إلى عنوان URL لملف إحدى الإضافات باستخدام chrome.runtime.getURL()
واستخدام النتيجة نفسها المستخدَمة في عناوين URL الأخرى.
// Code for displaying EXTENSION_DIR/images/myimage.png:
var imgURL = chrome.runtime.getURL("images/myimage.png");
document.getElementById("someImage").src = imgURL;
بالإضافة إلى ذلك، يمكن للنص البرمجي للمحتوى الوصول إلى واجهات برمجة تطبيقات Chrome التالية مباشرةً:
لا يمكن للنصوص البرمجية للمحتوى الوصول إلى واجهات برمجة تطبيقات أخرى مباشرةً.
العمل في عوالم معزولة
تعمل نصوص المحتوى البرمجية في بيئة معزولة، ما يسمح لها بإجراء تغييرات على بيئة JavaScript بدون التأثير في الصفحة أو نصوص المحتوى البرمجية الإضافية.
يمكن تشغيل إضافة في صفحة ويب باستخدام رمز مشابه للمثال أدناه.
<html>
<button id="mybutton">click me</button>
<script>
var greeting = "hello, ";
var button = document.getElementById("mybutton");
button.person_name = "Bob";
button.addEventListener("click", function() {
alert(greeting + button.person_name + ".");
}, false);
</script>
</html>
يمكن أن تُدخل هذه الإضافة النص البرمجي التالي للمحتوى.
var greeting = "hola, ";
var button = document.getElementById("mybutton");
button.person_name = "Roberto";
button.addEventListener("click", function() {
alert(greeting + button.person_name + ".");
}, false);
سيظهر كلا التنبيهَين في حال الضغط على الزر.
لا تسمح العوالم المنعزلة للنصوص البرمجية للمحتوى والإضافات وصفحات الويب بالوصول إلى أي متغيّرات أو وظائف أنشأها الآخرون. ويمنح هذا أيضًا نصوص برمجية المحتوى إمكانية تفعيل وظائف لا يُفترَض أن تكون متاحة لصفحة الويب.
إدراج نصوص برمجية
يمكن إدراج نصوص برمجية للمحتوى بشكل آلي أو بشكل صريح.
الإدراج آليًا
استخدِم ميزة "الإدراج الآلي" لنصوص المحتوى التي يجب عرضها في مناسبات معيّنة.
لإدراج نص برمجي للمحتوى، يجب تقديم إذن activeTab في البيان. يمنح هذا الإذن الوصول الآمن إلى مضيف الموقع الإلكتروني النشط والوصول المؤقت إلى إذن علامات التبويب ، ما يتيح تشغيل نص المحتوى في علامة التبويب النشطة الحالية بدون تحديد أذونات مصادر متعددة.
{
"name": "My extension",
...
"permissions": [
"activeTab"
],
...
}
يمكن إدخال النصوص البرمجية للمحتوى كرمز.
chrome.runtime.onMessage.addListener(
function(message, callback) {
if (message == "changeColor"){
chrome.tabs.executeScript({
code: 'document.body.style.backgroundColor="orange"'
});
}
});
أو يمكن إدخال ملف كامل.
chrome.runtime.onMessage.addListener(
function(message, callback) {
if (message == "runContentScript"){
chrome.tabs.executeScript({
file: 'contentScript.js'
});
}
});
الإدراج بشكل صريح
استخدِم ميزة "الإدراج التعريفي" للنصوص البرمجية للمحتوى التي يجب تشغيلها تلقائيًا على صفحات محدّدة.
يتم تسجيل النصوص البرمجية المُستخدَمة في الحقل "content_scripts"
في البيان.
ويمكن أن تتضمّن ملفات JavaScript أو ملفات CSS أو كليهما. يجب أن تحدّد كل نصوص المحتوى البرمجية التي يتم تشغيلها تلقائيًا
أنماط المطابقة.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"css": ["myStyles.css"],
"js": ["contentScript.js"]
}
],
...
}
الاسم | النوع | الوصف |
---|---|---|
matches {: #matches } |
مطلوبة تُستخدَم لتحديد الصفحات التي سيتم إدراج نص المحتوى هذا فيها. اطّلِع على أنماط المطابقة للحصول على مزيد من التفاصيل حول بنية هذه السلاسل وأنماط المطابقة والعناصر الشاملة للحصول على معلومات عن كيفية استبعاد عناوين URL. | |
css {: #css } |
اختياري قائمة ملفات CSS التي سيتم إدراجها في الصفحات المطابقة ويتمّ إدراجها بالترتيب الذي تظهر به في هذه الصفيف، قبل إنشاء أيّ عنصر DOM أو عرضه للصفحة. | |
js {: #js } |
اختياري قائمة ملفات JavaScript التي سيتم إدراجها في الصفحات المطابقة ويتم إدراجها بالترتيب الذي تظهر به في هذه الصفيف. | |
match_about_blank {: #match_about_blank } |
قيمة منطقية | اختياري ما إذا كان يجب إدراج النص البرمجي في إطار about:blank حيث يتطابق الإطار الرئيسي أو الإطار الافتتاحي مع أحد الأنماط المعلَن عنها في matches . الإعداد التلقائي هو false . |
استبعاد المطابقات والنطاقات الشاملة
يمكن تخصيص مطابقة الصفحة المحدّدة من خلال تضمين الحقول التالية في بيان تسجيل التطبيق.
الاسم | النوع | الوصف |
---|---|---|
exclude_matches {: #exclude_matches } |
اختياري يستبعد الصفحات التي سيتم إدراج نص برمجي للمحتوى فيها. اطّلِع على أنماط المطابقة للحصول على مزيد من التفاصيل حول بنية هذه السلاسل. | |
include_globs {: #include_globs } |
اختياري يتم تطبيقها بعد matches لتضمين عناوين URL التي تتطابق أيضًا مع هذا النطاق الشامل. يهدف إلى محاكاة الكلمة الرئيسية @include في Greasemonkey. |
|
exclude_globs {: #exclude_globs } |
اختياري يتم تطبيقها بعد matches لاستبعاد عناوين URL التي تتطابق مع هذا النطاق الشامل. يهدف إلى محاكاة الكلمة الرئيسية @exclude Greasemonkey. |
سيتمّ إدراج نصّ المحتوى في صفحة إذا كان عنوان URL الخاص بها يتطابق مع أيّ نمط matches
وأيّ نمط
include_globs
، ما دام عنوان URL لا يتطابق أيضًا مع نمط exclude_matches
أو
exclude_globs
.
بما أنّ سمة matches
مطلوبة، لا يمكن استخدام السمات exclude_matches
وinclude_globs
وexclude_globs
إلا لحصر الصفحات التي ستتأثر.
ستُدخل الإضافة التالية نص المحتوى البرمجي في http://www.nytimes.com/ health ولكن ليس في http://www.nytimes.com/ business .
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"exclude_matches": ["*://*/*business*"],
"js": ["contentScript.js"]
}
],
...
}
تتبع سمات النطاقات بنية مختلفة وأكثر مرونة من نماذج المطابقة. إنّ سلاسل التجميع المقبولة هي عناوين URL التي قد تحتوي على علامات النجمة وعلامات الاستفهام "أحرف البدل". تتطابق علامة النجمة * مع أي سلسلة بأي طول، بما في ذلك السلسلة الفارغة، في حين تتطابق علامة الاستفهام ؟ يتطابق مع أي حرف مفرد.
على سبيل المثال، يتطابق نطاق النطاق الشامل http:// ??? .example.com/foo/ * مع أيٍّ ممّا يلي:
- http:// www .example.com/foo /bar
- http:// the .example.com/foo /
ومع ذلك، لا يتطابق مع ما يلي:
- http:// my .example.com/foo/bar
- http:// example .com/foo/
- http://www.example.com/foo
سيؤدي هذا الملحق إلى إدراج نص المحتوى في http:/www.nytimes.com/ arts /index.html و http://www.nytimes.com/ jobs /index.html ولكن ليس في http://www.nytimes.com/ sports /index.html.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"include_globs": ["*nytimes.com/???s/*"],
"js": ["contentScript.js"]
}
],
...
}
ستُدخل هذه الإضافة نص المحتوى في http:// history .nytimes.com و http://.nytimes.com/ history ولكن ليس في http:// science .nytimes.com أو http://www.nytimes.com/ science .
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"exclude_globs": ["*science*"],
"js": ["contentScript.js"]
}
],
...
}
يمكن تضمين واحد أو كل هذه العناصر أو بعضها لتحقيق النطاق الصحيح.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"exclude_matches": ["*://*/*business*"],
"include_globs": ["*nytimes.com/???s/*"],
"exclude_globs": ["*science*"],
"js": ["contentScript.js"]
}
],
...
}
وقت التنفيذ
يتم التحكّم في وقت إدخال ملفات JavaScript في صفحة الويب من خلال الحقل run_at
. الحقل
المفضّل والتلقائي هو "document_idle"
، ولكن يمكن أيضًا تحديده على أنّه "document_start"
أو
"document_end"
إذا لزم الأمر.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
الاسم | النوع | الوصف |
---|---|---|
document_idle {: #document_idle } |
سلسلة | الصورة المفضَّلة: استخدِم "document_idle" كلما أمكن.يختار المتصفّح وقتًا لإدراج النصوص البرمجية بين "document_end" وبعد بدء حدث windowonload مباشرةً. تعتمد اللحظة الدقيقة للحقن على مدى تعقيد المستند والوقت الذي يستغرقه التحميل، ويتم تحسينها لسرعة تحميل الصفحة.لا تحتاج نصوص JavaScript التي يتم تنفيذها في "document_idle" إلى الانتظار لرصد حدث window.onload ، لأنّه من المؤكد أن يتم تنفيذها بعد اكتمال نموذج DOM. إذا كان النص البرمجي بحاجة إلى التنفيذ بعد window.onload ، يمكن للإضافة التحقّق مما إذا كان onload قد تم تشغيله من خلال استخدام السمة document.readyState . |
document_start {: #document_start } |
سلسلة | يتمّ إدراج النصوص البرمجية بعد أيّ ملفات من css ، ولكن قبل إنشاء أيّ عنصر تحكم في نموذج البيانات أو تنفيذ أيّ نصّ برمجي آخر. |
document_end {: #document_end } |
سلسلة | يتمّ حقن النصوص البرمجية فور اكتمال عنصر DOM، ولكن قبل تحميل الموارد الفرعية، مثل الصور والأطر. |
تحديد الإطارات
يسمح الحقل "all_frames"
للإضافات بتحديد ما إذا كان يجب
إدراج ملفات JavaScript وCSS في جميع الإطارات التي تتطابق مع متطلبات عنوان URL المحدّد أو في الإطار العلوي فقط في علامة تبويب.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"all_frames": true,
"js": ["contentScript.js"]
}
],
...
}
الاسم | النوع | الوصف |
---|---|---|
all_frames {: #all_frames } |
قيمة منطقية | اختياري القيمة التلقائية هي false ، ما يعني أنّه تتم مطابقة اللقطة العلوية فقط.في حال تحديد true ، سيتم إدراجها في جميع اللقطات، حتى إذا لم تكن اللقطة هي اللقطة العلوية في علامة التبويب. يتم التحقّق من كل إطار بشكل مستقل من متطلبات عنوان URL، ولن يتم إدراجه في الإطارات الفرعية في حال عدم استيفاء متطلبات عنوان URL. |
التواصل مع صفحة التضمين
على الرغم من أنّ بيئات تنفيذ النصوص البرمجية للمحتوى والصفحات التي تستضيفها معزولة عن بعضها، إلا أنّها تشترك في الوصول إلى نموذج DOM للصفحة. إذا أرادت الصفحة التواصل مع نصّ المحتوى، أو مع الإضافة من خلال نصّ المحتوى، يجب أن تفعل ذلك من خلال نموذج DOM المشترَك.
يمكن تنفيذ مثال باستخدام window.postMessage
:
var port = chrome.runtime.connect();
window.addEventListener("message", function(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",
function() {
window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");
}, false);
تنشر الصفحة example.html التي لا تشكّل إضافة رسائل إلى نفسها. يتم اعتراض هذه الرسالة وتفتيشها من خلال النص البرمجي للمحتوى، ثم يتم نشرها في عملية إضافة البيانات. بهذه الطريقة، تُنشئ الصفحة قناة تواصل مع عملية التمديد. ويمكن إجراء العكس من خلال وسائل مشابهة.
الحفاظ على أمانك
على الرغم من أنّ العوالم المعزولة توفّر طبقة حماية، يمكن أن يؤدي استخدام النصوص البرمجية للمحتوى إلى تعريض الإضافة وصفحة الويب للثغرات الأمنية. إذا كان نص المحتوى يتلقّى محتوى من موقع إلكتروني منفصل، مثل إنشاء XMLHttpRequest، يجب الانتباه إلى فلترة هجمات النصوص البرمجية على مستوى المواقع الإلكترونية قبل حقنها. يجب التواصل عبر HTTPS فقط لتجنُّب هجمات "man-in-the-middle".
احرص على الفلترة بحثًا عن صفحات الويب الضارّة. على سبيل المثال، الأنماط التالية خطيرة:
var data = document.getElementById("json-data")
// WARNING! Might be evaluating an evil script!
var parsed = eval("(" + data + ")")
var elmt_id = ...
// WARNING! elmt_id might be "); ... evil script ... //"!
window.setTimeout("animate(" + elmt_id + ")", 200);
بدلاً من ذلك، يُفضَّل استخدام واجهات برمجة تطبيقات أكثر أمانًا لا تعمل على تنفيذ النصوص البرمجية:
var data = document.getElementById("json-data")
// JSON.parse does not evaluate the attacker's scripts.
var parsed = JSON.parse(data);
var elmt_id = ...
// The closure form of setTimeout does not evaluate scripts.
window.setTimeout(function() {
animate(elmt_id);
}, 200);