İçerik komut dosyaları, web sayfaları bağlamında çalışan dosyalardır. Standart Belge Nesne Modeli'ni (DOM) kullanarak tarayıcının ziyaret ettiği web sayfalarının ayrıntılarını okuyabilir, bu sayfalarda değişiklik yapabilir ve bilgileri üst uzantılarına iletebilirler.
İçerik komut dosyası özelliklerini anlama
İçerik komut dosyaları, uzantıyla mesaj alışverişi yaparak üst uzantıları tarafından kullanılan Chrome API'lerine erişebilir. Ayrıca, chrome.runtime.getURL() ile bir uzantı dosyasının URL'sine erişebilir ve sonucu diğer URL'lerle aynı şekilde kullanabilirler.
// Code for displaying EXTENSION_DIR/images/myimage.png:
var imgURL = chrome.runtime.getURL("images/myimage.png");
document.getElementById("someImage").src = imgURL;
Ayrıca içerik komut dosyası, aşağıdaki Chrome API'lerine doğrudan erişebilir:
İçerik komut dosyaları diğer API'lere doğrudan erişemez.
İzole edilmiş dünyalarda çalışma
İçerik komut dosyaları, izole bir ortamda çalışır. Bu sayede, bir içerik komut dosyası, sayfayla veya ek içerik komut dosyalarıyla çakışmadan JavaScript ortamında değişiklik yapabilir.
Uzantılar, aşağıdaki örneğe benzer kod içeren web sayfalarında çalışabilir.
<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>
Bu uzantı, aşağıdaki içerik komut dosyasını yerleştirebilir.
var greeting = "hola, ";
var button = document.getElementById("mybutton");
button.person_name = "Roberto";
button.addEventListener("click", function() {
alert(greeting + button.person_name + ".");
}, false);
Düğmeye basıldığında her iki uyarı da gösterilir.
İzole edilmiş dünyalar, içerik komut dosyalarının, uzantının ve web sayfasının diğerleri tarafından oluşturulan değişkenlere veya işlevlere erişmesine izin vermez. Bu durum, içerik komut dosyalarına web sayfasının erişememesi gereken işlevleri etkinleştirme olanağı da tanır.
Komut dosyası yerleştirme
İçerik komut dosyaları programatik veya bildirimsel olarak eklenebilir.
Programatik olarak yerleştirme
Belirli durumlarda çalışması gereken içerik komut dosyaları için programatik yerleştirme kullanın.
Programatik içerik komut dosyası eklemek için manifest dosyasında activeTab iznini sağlayın. Bu, etkin sitenin ana makinesine güvenli erişim ve sekmeler iznine geçici erişim sağlar. Böylece, içerik komut dosyası kaynaklar arası izinler belirtilmeden mevcut etkin sekmede çalıştırılabilir.
{
"name": "My extension",
...
"permissions": [
"activeTab"
],
...
}
İçerik komut dosyaları kod olarak yerleştirilebilir.
chrome.runtime.onMessage.addListener(
function(message, callback) {
if (message == "changeColor"){
chrome.tabs.executeScript({
code: 'document.body.style.backgroundColor="orange"'
});
}
});
İsterseniz dosyanın tamamını da ekleyebilirsiniz.
chrome.runtime.onMessage.addListener(
function(message, callback) {
if (message == "runContentScript"){
chrome.tabs.executeScript({
file: 'contentScript.js'
});
}
});
Bildirimsel olarak yerleştirme
Belirli sayfalarda otomatik olarak çalıştırılması gereken içerik komut dosyaları için bildirimli yerleştirme kullanın.
Bildirimli olarak yerleştirilen komut dosyaları, manifest'te "content_scripts" alanı altında kaydedilir.
JavaScript dosyaları, CSS dosyaları veya her ikisi de olabilir. Otomatik olarak çalışan tüm içerik komut dosyaları eşleşme kalıplarını belirtmelidir.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"css": ["myStyles.css"],
"js": ["contentScript.js"]
}
],
...
}
| Ad | Tür | Açıklama |
|---|---|---|
matches {: #matches } |
Zorunlu. Bu içerik komut dosyasının hangi sayfalara ekleneceğini belirtir. Bu dizelerin söz dizimi hakkında daha fazla bilgi için Eşleşme Kalıpları, URL'leri hariç tutma hakkında bilgi için ise Eşleşme kalıpları ve globlar başlıklı makaleyi inceleyin. | |
css {: #css } |
İsteğe bağlıdır. Eşleşen sayfalara yerleştirilecek CSS dosyalarının listesi. Bunlar, bu dizide göründükleri sırayla, sayfa için herhangi bir DOM oluşturulmadan veya görüntülenmeden önce yerleştirilir. | |
js {: #js } |
İsteğe bağlıdır. Eşleşen sayfalara yerleştirilecek JavaScript dosyalarının listesi. Bunlar, bu dizide göründükleri sırayla yerleştirilir. | |
match_about_blank {: #match_about_blank } |
boolean | İsteğe bağlıdır. Komut dosyasının, üst veya açıcı çerçevenin matches içinde belirtilen kalıplardan biriyle eşleştiği bir about:blank çerçevesine yerleştirilip yerleştirilmeyeceği. Varsayılan olarak false değerine ayarlanır. |
Eşleşmeleri ve globları hariç tutma
Belirtilen sayfa eşleştirme, aşağıdaki alanlar manifest kaydına eklenerek özelleştirilebilir.
| Ad | Tür | Açıklama |
|---|---|---|
exclude_matches {: #exclude_matches } |
İsteğe bağlıdır. Bu içerik komut dosyasının aksi takdirde içine yerleştirileceği sayfaları hariç tutar. Bu dizelerin söz dizimi hakkında daha fazla bilgi için Eşleşme Kalıpları bölümüne bakın. | |
include_globs {: #include_globs } |
İsteğe bağlıdır. Yalnızca bu glob ile de eşleşen URL'leri içerecek şekilde matches tarihinden sonra uygulanır. @include Greasemonkey anahtar kelimesini taklit etmek için tasarlanmıştır. |
|
exclude_globs {: #exclude_globs } |
İsteğe bağlıdır. Bu glob ile eşleşen URL'leri hariç tutmak için matches'dan sonra uygulanır. @excludeGreasemonkey anahtar kelimesini taklit etmek için tasarlanmıştır. |
URL, matches veya include_globs kalıbıyla eşleştiği sürece içerik komut dosyası sayfaya yerleştirilir. Ancak URL, exclude_matches veya exclude_globs kalıbıyla da eşleşmemelidir.
matches özelliği zorunlu olduğundan exclude_matches, include_globs ve exclude_globs yalnızca hangi sayfaların etkileneceğini sınırlamak için kullanılabilir.
Aşağıdaki uzantı, içerik komut dosyasını http://www.nytimes.com/ health adresine yerleştirir ancak http://www.nytimes.com/ business adresine yerleştirmez .
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"exclude_matches": ["*://*/*business*"],
"js": ["contentScript.js"]
}
],
...
}
Glob özellikleri, eşleme kalıplarından farklı ve daha esnek bir söz dizimi kullanır. Kabul edilebilir glob dizeleri, "joker karakter" yıldız işaretleri ve soru işaretleri içerebilen URL'lerdir. Yıldız işareti *, boş dize dahil olmak üzere herhangi bir uzunluktaki herhangi bir dizeyle eşleşirken soru işareti ? herhangi bir tek karakterle eşleşir.
Örneğin, http:// ??? .example.com/foo/ * glob'u aşağıdakilerden herhangi biriyle eşleşir:
- http:// www .example.com/foo /bar
- http:// the .example.com/foo /
Ancak aşağıdaki öğelerle eşleşmez:
- http:// my .example.com/foo/bar
- http:// example .com/foo/
- http://www.example.com/foo
Bu uzantı, içerik komut dosyasını http:/www.nytimes.com/ arts /index.html ve http://www.nytimes.com/ jobs /index.html sayfalarına yerleştirir ancak http://www.nytimes.com/ sports /index.html sayfasına yerleştirmez.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"include_globs": ["*nytimes.com/???s/*"],
"js": ["contentScript.js"]
}
],
...
}
Bu uzantı, içerik komut dosyasını http:// history .nytimes.com ve http://.nytimes.com/ history adreslerine yerleştirir ancak http:// science .nytimes.com veya http://www.nytimes.com/ science adreslerine yerleştirmez .
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"exclude_globs": ["*science*"],
"js": ["contentScript.js"]
}
],
...
}
Doğru kapsamı elde etmek için bunlardan biri, tamamı veya bir kısmı dahil edilebilir.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"exclude_matches": ["*://*/*business*"],
"include_globs": ["*nytimes.com/???s/*"],
"exclude_globs": ["*science*"],
"js": ["contentScript.js"]
}
],
...
}
Süre
JavaScript dosyalarının web sayfasına yerleştirilip yerleştirilmeyeceği run_at alanı tarafından kontrol edilir. Tercih edilen ve varsayılan alan "document_idle"'dır ancak gerekirse "document_start" veya "document_end" olarak da belirtilebilir.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
| Ad | Tür | Açıklama |
|---|---|---|
document_idle {: #document_idle } |
dize | Tercih edilen. Mümkün olduğunda "document_idle" kullanın.Tarayıcı, "document_end" ile windowonload etkinliği tetiklendikten hemen sonraki bir zamanı seçerek komut dosyalarını yerleştirir. Eklemenin tam olarak ne zaman yapılacağı, belgenin karmaşıklığına ve yüklenmesinin ne kadar sürdüğüne bağlıdır ve sayfa yükleme hızı için optimize edilmiştir."document_idle" zamanında çalışan içerik komut dosyalarının window.onload etkinliğini dinlemesi gerekmez. Bu komut dosyalarının, DOM tamamlandıktan sonra çalışacağı garanti edilir. Bir komut dosyasının kesinlikle window.onload'dan sonra çalışması gerekiyorsa uzantı, document.readyState özelliğini kullanarak onload'nın zaten tetiklenip tetiklenmediğini kontrol edebilir. |
document_start {: #document_start } |
dize | Komut dosyaları, css kaynaklı dosyalardan sonra ancak başka bir DOM oluşturulmadan veya başka bir komut dosyası çalıştırılmadan önce eklenir. |
document_end {: #document_end } |
dize | Komut dosyaları, DOM tamamlandıktan hemen sonra ancak resimler ve çerçeveler gibi alt kaynaklar yüklenmeden önce yerleştirilir. |
Çerçeveleri belirtme
"all_frames" alanı, uzantının JavaScript ve CSS dosyalarının belirtilen URL'yle ilgili koşullarla eşleşen tüm çerçevelere mi yoksa yalnızca bir sekmedeki en üstteki çerçeveye mi yerleştirileceğini belirtmesine olanak tanır.
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"all_frames": true,
"js": ["contentScript.js"]
}
],
...
}
| Ad | Tür | Açıklama |
|---|---|---|
all_frames {: #all_frames } |
boolean | İsteğe bağlıdır. Varsayılan olarak false'dır. Bu, yalnızca en üstteki çerçevenin eşleştirildiği anlamına gelir.true belirtilirse sekmedeki en üstteki çerçeve olmasa bile tüm çerçevelere yerleştirilir. Her çerçeve, URL'yle ilgili koşullar açısından bağımsız olarak kontrol edilir. URL'yle ilgili koşullar karşılanmazsa alt çerçevelere yerleştirilmez. |
Yerleştirme sayfasıyla iletişim
İçerik komut dosyalarının ve bunları barındıran sayfaların yürütme ortamları birbirinden izole edilmiş olsa da sayfanın DOM'una erişimi paylaşırlar. Sayfa, içerik komut dosyasıyla veya içerik komut dosyası üzerinden uzantıyla iletişim kurmak istiyorsa bunu paylaşılan DOM üzerinden yapmalıdır.
window.postMessage kullanılarak bir örnek verilebilir:
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);
Uzantı olmayan sayfa (ör. example.html) kendi kendine mesaj gönderir. Bu ileti, içerik komut dosyası tarafından yakalanıp incelenir ve ardından uzantı sürecine gönderilir. Bu şekilde sayfa, uzantı işlemiyle iletişim hattı oluşturur. Benzer yöntemlerle geri alma işlemi yapılabilir.
Güvende kalın
İzole edilmiş dünyalar bir koruma katmanı sağlasa da içerik komut dosyalarının kullanılması, uzantıda ve web sayfasında güvenlik açıkları oluşturabilir. İçerik komut dosyası, XMLHttpRequest oluşturma gibi işlemlerle ayrı bir web sitesinden içerik alıyorsa içeriği eklemeden önce siteler arası komut dosyası çalıştırma saldırılarına karşı filtrelemeye dikkat edin. "man-in-the-middle" saldırılarından kaçınmak için yalnızca HTTPS üzerinden iletişim kurun.
Kötü amaçlı web sayfalarını filtrelediğinizden emin olun. Örneğin, aşağıdaki kalıplar tehlikelidir:
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);
Bunun yerine, komut dosyası çalıştırmayan daha güvenli API'leri tercih edin:
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);