İçerik komut dosyaları

İçerik komut dosyaları, web sayfaları bağlamında çalışan dosyalardır. Standart Belge Nesnesi 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 üst uzantılarına bilgi aktarabilirler.

İçerik komut dosyası özelliklerini anlama

İçerik komut dosyaları, uzantılarıyla mesaj alışverişinde bulunarak üst uzantılarının kullandığı Chrome API'lerine erişebilir. Ayrıca chrome.runtime.getURL() ile bir uzantının 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 dünyada çalışır. Bu sayede, içerik komut dosyaları sayfa veya ek içerik komut dosyalarıyla çelişmeden JavaScript ortamında değişiklik yapabilir.

Bir uzantı, aşağıdaki örneğe benzer kod içeren bir web sayfası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ılırsa her iki uyarı da gösterilir.

İzole dünyalar, içerik komut dosyalarının, uzantının ve web sayfasının diğer taraflarca oluşturulan değişkenlere veya işlevlere erişmesine izin vermez. Bu, 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 belirleyici olarak eklenebilir.

Programatik olarak ekleme

Belirli durumlarda çalıştırılması gereken içerik komut dosyaları için programatik enjeksiyon 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 belirtmeden mevcut etkin sekmede çalışabilir.

{
  "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"'
      });
    }
  });

Dilerseniz bir dosyanın tamamı da eklenebilir.

chrome.runtime.onMessage.addListener(
  function(message, callback) {
    if (message == "runContentScript"){
      chrome.tabs.executeScript({
        file: 'contentScript.js'
      });
    }
  });

Açıklayıcı bir şekilde ekleme

Belirtilen sayfalarda otomatik olarak çalıştırılması gereken içerik komut dosyaları için açıklayıcı ekleme kullanın.

Açık beyanla enjekte edilen komut dosyaları, manifest'e "content_scripts" alanının altına kaydedilir. Bunlar JavaScript dosyaları, CSS dosyaları veya her ikisi olabilir. Tüm otomatik çalıştırılan içerik komut dosyaları eşleme 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 } dize dizisi Zorunludur. 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ı bölümüne, URL'lerin nasıl hariç tutulacağı hakkında bilgi için Eşleşme kalıpları ve genel eşlemeler bölümüne bakın.
css {: #css } dize dizisi İsteğe bağlıdır. Eşleşen sayfalara eklenecek CSS dosyalarının listesi. Bunlar, sayfa için herhangi bir DOM oluşturulmadan veya görüntülenmeden önce bu dizgede göründükleri sırada eklenir.
js {: #js } dize dizisi İsteğe bağlıdır. Eşleşen sayfalara eklenecek JavaScript dosyalarının listesi. Bunlar, bu dizgede göründükleri sırayla eklenir.
match_about_blank {: #match_about_blank } boolean İsteğe bağlıdır. Komut dosyasının, üst veya başlatıcı çerçevenin matches içinde tanımlanan kalıplardan biriyle eşleştiği bir about:blank çerçevesine eklenip eklenmeyeceği. Varsayılan olarak false değerine ayarlanır.

Eşleşmeleri ve genel eşlemelerini hariç tutma

Belirtilen sayfa eşleştirmesi, manifest kaydına aşağıdaki alanlar eklenerek özelleştirilebilir.

Ad Tür Açıklama
exclude_matches {: #exclude_matches } dize dizisi İsteğe bağlıdır. Bu içerik komut dosyasının aksi takdirde yerleştirileceği sayfaları hariç tutar. Bu dizelerin söz dizimi hakkında daha fazla bilgi için Eşleşme Kalıpları başlıklı makaleyi inceleyin.
include_globs {: #include_globs } dize dizisi İsteğe bağlıdır. Yalnızca bu genel ifadeyle eşleşen URL'leri dahil etmek için matches'ten sonra uygulanır. @include Greasemonkey anahtar kelimesini taklit etmek için tasarlanmıştır.
exclude_globs {: #exclude_globs } dize dizisi İsteğe bağlıdır. Bu genel ifadeyle eşleşen URL'leri hariç tutmak için matches'ten sonra uygulanır. @excludeGreasemonkey anahtar kelimesini taklit etmek için tasarlanmıştır.

İçerik komut dosyası, URL'si herhangi bir matches kalıbıyla ve herhangi bir include_globs kalıbıyla eşleşiyorsa sayfaya eklenir. Ancak URL'nin exclude_matches veya exclude_globs kalıbıyla eşleşmemesi gerekir.

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 edilen genel dize, "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 dizeyle eşleşir. herhangi bir tek karakterle eşleşir.

Örneğin, http:// ??? .example.com/foo/ * genel ifadesi aşağıdakilerden herhangi biriyle eşleşir:

  • http:// www .example.com/foo /bar
  • http:// the .example.com/foo /

Ancak aşağıdakilerle 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 adreslerine ekler ancak http://www.nytimes.com/ sports /index.html adresine eklemez.

{
  "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 enjekte eder ancak http:// science .nytimes.com veya http://www.nytimes.com/ science adreslerine enjekte etmez .

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

Doğru kapsama ulaşmak için bunlardan biri, tümü veya bazıları 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 ne zaman ekleneceği run_at alanı tarafından kontrol edilir. Tercih edilen ve varsayılan alan "document_idle"'tü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ğinin hemen ardından komut dosyaları eklemek için bir zaman seçer. Enjeksiyon tam olarak ne zaman gerçekleşeceği, belgenin ne kadar karmaşık olduğuna ve yüklenmesinin ne kadar sürdüğüne bağlıdır ve sayfa yükleme hızı için optimize edilir.

"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'ten sonra çalıştırılması gerekiyorsa uzantı, document.readyState mülkünü kullanarak onload'un tetiklenip tetiklenmediğini kontrol edebilir.
document_start {: #document_start } dize Komut dosyaları, css'deki 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 resim ve çerçeve gibi alt kaynakların yüklenmesinden önce eklenir.

Çerçeveleri belirtme

"all_frames" alanı, uzantının JavaScript ve CSS dosyalarının belirtilen URL koşullarını karşılayan tüm çerçevelere mi yoksa yalnızca sekmedeki en üst çerçeveye mi ekleneceğ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 değerini alır. Bu, yalnızca en üst karenin eşleştiği anlamına gelir.

true belirtilirse kare sekmedeki en üst kare olmasa bile tüm karelere eklenir. Her çerçeve, URL koşulları açısından bağımsız olarak kontrol edilir. URL koşulları karşılanmıyorsa alt çerçevelere eklenmez.

Yerleştirme sayfasıyla iletişim

İçerik komut dosyalarının yürütme ortamları ve bunları barındıran sayfalar birbirinden izole olsa da sayfanın DOM'una erişimi paylaşırlar. Sayfa, içerik komut dosyasıyla veya içerik komut dosyası aracılığıyla uzantı ile 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 example.html sayfası, kendisine mesaj gönderir. Bu ileti, içerik komut dosyası tarafından yakalanıp incelenir ve ardından uzantı işlemine gönderilir. Bu sayede sayfa, uzantı süreciyle iletişim kurar. Benzer yöntemlerle tersini de yapabilirsiniz.

Güvende kalın

İzole dünyalar bir koruma katmanı sağlarken içerik komut dosyalarının kullanılması, uzantı ve web sayfasında güvenlik açıkları oluşturabilir. İçerik komut dosyası, ayrı bir web sitesinden içerik alıyorsa (ör. XMLHttpRequest oluşturma) içeriği eklemeden önce içerik siteler arası komut dosyası çalıştırma saldırılarını filtrelediğinizden emin olun. "man-in-the-middle" saldırılarını önlemek 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);