İçerik komut dosyaları

İçerik komut dosyaları, web sayfaları bağlamında çalışan dosyalardır. Standart Dokümanı kullanarak Nesne Modeli (DOM) ile çalışırken, tarayıcının ziyaret ettiği web sayfalarının ayrıntılarını okuyabilir, ve bilgileri üst uzantılarına iletebilir.

İçerik komut dosyası özelliklerini anlama

İçerik komut dosyaları aşağıdaki uzantı API'lerine doğrudan erişebilir:

İçerik komut dosyaları diğer API'lere doğrudan erişemez. Ancak uzantınızın diğer kısımlarıyla mesaj alışverişinde bulunarak dolaylı olarak bunlara erişebilirler.

Uzantınızdaki diğer dosyalara bir içerik komut dosyasından da erişmek için fetch() gibi API'ler. Bunun için bunları web'den erişilebilen kaynaklara sahip olması gerekir. Bunun aynı zamanda kaynakları aynı sitede çalışan birinci veya üçüncü taraf komut dosyaları.

Issız dünyalarda çalışın

İçerik komut dosyaları izole bir dünyada yaşar ve bu sayede, içerik komut dosyalarının Sayfa veya diğer uzantılarla çakışmayan JavaScript ortamının içerik komut dosyaları.

Uzantılar, web sayfasında aşağıdaki örneğe benzer bir kodla çalışabilir.

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>

Bu uzantı, Komut dosyaları yerleştirme bölümüne bakın.

content-script.js

var greeting = "hola, ";
var button = document.getElementById("mybutton");
button.person_name = "Roberto";
button.addEventListener(
    "click", () => alert(greeting + button.person_name + "."), false);

Bu değişiklikle birlikte, düğme tıklandığında her iki uyarı da sırayla görünür.

Komut dosyası ekle

İçerik komut dosyaları statik olarak bildirilebilir, bildirilebilir dinamik olarak veya programatik olarak eklenir.

Statik bildirimlerle yerleştirme

Otomatik olarak yapılması gereken komut dosyaları için manifest.json dosyasındaki statik içerik komut dosyası bildirimlerini kullanın iyi bilinen bir grup sayfada çalışmasıdır.

Statik olarak bildirilen komut dosyaları, manifeste "content_scripts" anahtarı altında kaydedilir. JavaScript dosyalarını, CSS dosyalarını veya her ikisini birden içerebilir. Otomatik olarak çalıştırılan tüm içerik komut dosyaları, eşleşme kalıpları hakkında daha fazla bilgi edinin.

manifest.json

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

Ad Tür Açıklama
matches dize dizisi Zorunludur. Bu içerik komut dosyasının hangi sayfalara yerleştirileceğini belirtir. Bu dizelerin söz dizimiyle ilgili ayrıntılar için Eşleme Kalıpları bölümüne bakın ve hariç tutma hakkında bilgi için Eşleşme kalıpları ve glob'ları URL'ler.
css dize dizisi İsteğe bağlıdır. Eşleşen sayfalara eklenecek CSS dosyalarının listesi. Bunlar: herhangi bir DOM oluşturulmadan veya görüntülenmeden önce, bu dizide göründükleri sırayla eklenir ekleyebilirsiniz.
js dize dizisi İsteğe bağlıdır. Eşleşen sayfalara eklenecek JavaScript dosyalarının listesi. Dosyalar bu dizide göründükleri sırayla eklenir. Bu listedeki her dize uzantının kök dizinindeki bir kaynağa giden göreli bir yol. Baştaki eğik çizgiler ("/"): otomatik olarak kırpılır.
run_at RunAt İsteğe bağlıdır. Komut dosyasının sayfaya ne zaman eklenmesi gerektiğini belirtir. Varsayılan değer: document_idle
match_about_blank boolean İsteğe bağlıdır. Komut dosyasının bir about:blank karesine yerleştirip yerleştirilmeyeceği üst veya açıcı çerçevenin matches. Varsayılan olarak yanlış değerine ayarlanır.
match_origin_as_fallback boolean İsteğe bağlıdır. Komut dosyasının oluşturulan karelere eşleşen bir kaynak tarafından oluşturulmuş ancak URL'si veya kaynağı doğrudan olmayan olduğunu görebilirsiniz. Bunlar, aşağıdakiler gibi farklı şemalara sahip kareleri içerir: about:, data:, blob: ve filesystem:. Şu kaynakları da inceleyin İlgili çerçevelere ekleme.
world ExecutionWorld İsteğe bağlıdır. Komut dosyasının yürütüleceği JavaScript dünyası. Varsayılan olarak ISOLATED değerine ayarlanır. Şu kaynakları da inceleyin İstikrarlı dünyalarda çalışın.

Dinamik bildirimlerle ekle

Dinamik içerik komut dosyaları, içerik komut dosyaları için eşleşme kalıpları olmadığında bilinen ana makinelere her zaman içerik komut dosyalarının yerleştirilmemesi gerektiği durumlar olabilir.

Chrome 96'da kullanıma sunulan dinamik bildirimler statik bildirimleri eklenmiş olsa da içerik komut dosyası nesnesi Chrome'a yöntemleri yerine chrome.scripting ad alanında manifest.json. Scripting API, uzantı geliştiricilerinin alıcı:

Statik bildirimler gibi dinamik bildirimler de JavaScript dosyalarını, CSS dosyalarını veya her ikisini birden içerebilir.

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

Programatik olarak ekleme

Etkinliklere yanıt olarak veya belirli bir zamanda çalışması gereken içerik komut dosyaları için programatik yerleştirmeyi kullanın etkinlikler.

Programatik olarak içerik komut dosyası eklemek için uzantınızın kod yerleştirilmeye çalıştığı sayfa. Ana makine izinleri bunları uzantınızın manifestinin bir parçası olarak veya geçici olarak "activeTab" kullanarak isteme.

Aşağıda, ActiveTab tabanlı bir uzantının farklı bir sürümü bulunmaktadır.

manifest.json:

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

İçerik komut dosyaları dosya olarak yerleştirilebilir.

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

Alternatif olarak, işlev gövdesi bir içerik komut dosyası olarak yerleştirilebilir ve yürütülebilir.

service-worker.js:

function injectedFunction() {
  document.body.style.backgroundColor = "orange";
}

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target : {tabId : tab.id},
    func : injectedFunction,
  });
});

Yerleştirilen işlevin chrome.scripting.executeScript() çağrısı, orijinal işlevin kendisi değildir. Sonuç olarak, fonksiyonun gövde bağımsız olmalıdır; işlevin dışındaki değişkenlere yapılan başvurular, içeriğin ReferenceError komutu gönderir.

İşlev olarak eklerken, işleve bağımsız değişkenler de aktarabilirsiniz.

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

Eşleşmeleri ve glob'ları hariç tutma

Belirtilen sayfa eşleşmesini özelleştirmek için aşağıdaki alanları bildirime ekleyin teşekkür ederiz.

Ad Tür Açıklama
exclude_matches dize dizisi İsteğe bağlıdır. Bu içerik komut dosyasının normalde yerleştirileceği sayfalar hariç tutulur emin olun. Eşleşme Kalıpları yardımcı olur.
include_globs dize dizisi İsteğe bağlıdır. matches tarihinden sonra, yalnızca aşağıdaki URL'leri dahil etmek için uygulandı: bu küreyle eşleşiyor. Bu, @include emülasyonu yapmak üzere tasarlanmıştır. Greasemonkey anahtar kelimesi.
exclude_globs dize dizisi İsteğe bağlıdır. Bununla eşleşen URL'leri hariç tutmak için matches tarihinden sonra uygulanır glob. @exclude emülasyonu kullanılması amaçlanmıştır Greasemonkey anahtar kelimesi.

Aşağıdakilerin her ikisi de doğruysa içerik komut dosyası sayfaya yerleştirilir:

  • Bu alanın URL'si herhangi bir matches kalıbı ve herhangi bir include_globs kalıbıyla eşleşiyor.
  • URL, bir exclude_matches veya exclude_globs kalıbıyla da eşleşmiyor. matches özelliği zorunlu olduğu için exclude_matches, include_globs ve exclude_globs yalnızca etkilenecek sayfaları sınırlamak için kullanılabilir.

Aşağıdaki uzantı, içerik komut dosyasını https://www.nytimes.com/health hedefine ekliyor ancak https://www.nytimes.com/business ile değil .

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

Küre mülkleri, eşleşme kalıplarından farklı ve daha esnek bir söz dizimi kullanır. Kabul edilebilir glob dizeler "joker karakter" içerebilecek URL'lerdir yıldız işaretleri ve soru işaretleri. Yıldız işareti (*) soru işareti (?) ile eşleşirken boş dize dahil herhangi bir uzunluktaki herhangi bir dizeyle eşleşir kullanabilirsiniz.

Örneğin, https://???.example.com/foo/\* glob'u aşağıdakilerden herhangi biriyle eşleşir:

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

Ancak aşağıdakilerle eşleşmez:

  • https://my.example.com/foo/bar
  • https://example.com/foo/
  • https://www.example.com/foo

Bu uzantı, içerik komut dosyasını https://www.nytimes.com/arts/index.html ve https://www.nytimes.com/jobs/index.htm*, ancak şuna hitap etmiyor: 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"]
    }
  ],
  ...
}

Bu uzantı, içerik komut dosyasını https://history.nytimes.com ve https://.nytimes.com/history ancak https://science.nytimes.com veya https://www.nytimes.com/science:

manifest.json

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

Doğru kapsama ulaşmak için bunlardan biri, tümü veya bazıları dahil edilebilir.

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

Süre

run_at alanı, JavaScript dosyalarının web sayfasına ne zaman yerleştirileceğini kontrol eder. Tercih edilen ve "document_idle" varsayılan değerdir. Diğer olası veriler için RunAt türüne bakın. değerler.

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" ],
}]);
Ad Tür Açıklama
document_idle dize Tercih edilir. Mümkün olduğunda "document_idle" kullanın.

Tarayıcı komut dosyalarının "document_end" ve hemen sonrasına yerleştirileceği bir zaman seçer window.onload olduğunu unutmayın. Ekleme anının tam sırası, dokümanın ne kadar karmaşık olduğuna ve yüklenmesi uzun sürer ve sayfa yükleme hızı için optimize edilmiştir.

İçerik komut dosyaları "document_idle" konumunda çalışırken, window.onload etkinliği için DOM tamamlandıktan sonra çalıştırılması garanti edilir. komut dosyasının window.onload tarihinden sonra kesinlikle çalışması gerekirse uzantı, onload, document.readyState kullanılarak zaten tetiklendi
document_start dize Komut dosyaları, css öğesindeki tüm dosyalardan sonra, ancak diğer DOM'lerden önce yerleştirilir. çalıştırıldığından emin olun.
document_end dize Komut dosyaları, DOM tamamlandıktan hemen sonra, ancak resimler ve çerçeveler yüklendi.

Çerçeveleri belirt

"all_frames" alanı, uzantının JavaScript ve CSS dosyalarının ayarlanması gerekip gerekmediğini belirtmesine olanak tanır. belirtilen URL gereklilikleriyle eşleşen tüm karelere veya bir sekmesinden yararlanın.

manifest.json

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

service-worker.js

chrome.scripting.registerContentScripts([{
  id: "test",
  matches : [ "https://*.nytimes.com/*" ],
  allFrames : true,
  js : [ "contentScript.js" ],
}]);
Ad Tür Açıklama
all_frames boolean İsteğe bağlıdır. Varsayılan olarak false değerine ayarlanır, yani yalnızca üst kare ile eşleşir.

true belirtilirse çerçeve, sekmenin en üst karesi değildir. Her kare URL için bağımsız olarak kontrol edilir gereksinimlerini karşılayın. URL gereksinimleri karşılanmazsa alt çerçevelere yerleştirilmez.

Uzantılar, komut dosyalarını eşleşen bir kendilerini eşleşmezler. Bu durumun söz konusu olduğu durumlarda ile oluşturulmuş ancak URL'leri bir uyumlu çerçeve tarafından oluşturulmayan komut dosyasının belirtilen örüntüleriyle eşleştiğinden emin olun.

Bu durum, bir uzantı about:, data:, blob: ve filesystem: şemalarına sahip. Böyle durumlarda URL, içerik komut dosyasının kalıbıyla eşleşmez (ve about: ve data:, URL'ye üst URL'yi veya kaynağı dahil etmeyin about:blank veya data:text/html,<html>Hello, World!</html>'de olduğu gibi). Ancak bu kareler yine de oluşturma çerçevesiyle ilişkilendirilebilir.

Uzantılar, bu çerçevelere yerleştirmek için Bir içerik komut dosyası spesifikasyonundaki "match_origin_as_fallback" özelliği manifest'ini kullanabilirsiniz.

manifest.json

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

Belirtildiğinde ve true değerine ayarlandığında Chrome, öğesini ayarlamak için çerçevenin çerçevenin URL'sini girin. Bunun hedef çerçevenin kaynağı (ör. data: URL'nin kaynağı boş).

Çerçeveyi başlatan, hedefi oluşturan veya gezinen çerçevedir çerçeve. Bu genellikle doğrudan ebeveyn veya açıcı olsa da ( (iFrame) bir iframe içinde gezinen bir çerçeve bulunur.

Bu, başlatıcı çerçevesinin başlangıç noktası ile karşılaştırıldığından, başlatan çerçeve olabileceğini belirtir. Bu çıkarımı daha açık hale getirmek için, Chrome "match_origin_as_fallback" ile belirtilen tüm içerik komut dosyalarını gerektirir * yolunu belirtmek için true olarak ayarlandı.

Hem "match_origin_as_fallback" hem de "match_about_blank" belirtildiğinde, "match_origin_as_fallback" önceliklidir.

Yerleştirme sayfasıyla iletişim

İçerik komut dosyalarının yürütme ortamları ve bunları barındıran sayfalar birbirinden bağımsız olsa da sayfanın DOM'sine erişimi paylaşırlar. Sayfa, content komut dosyası üzerinden veya içerik komut dosyası üzerinden yapılan uzantı aracılığıyla bunu paylaşılan DOM üzerinden yapmalıdır.

window.postMessage() kullanılarak bir örnek gerçekleştirilebilir:

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

Uzantı olmayan sayfa (example.html) kendisine mesaj gönderir. Bu ileti ele geçirilir ve içerik komut dosyası tarafından incelenir ve ardından uzantı işleminde yayınlanır. Bu şekilde, sayfa uzantı süreciyle bir iletişim hattı oluşturur. Bunun tam tersi, anlamına gelir.

Uzantı dosyalarına erişme

Bir uzantı dosyasına içerik komut dosyasından erişmek için Aşağıdaki örnekte (content.js) gösterildiği gibi uzantı öğenizin mutlak URL'sini almak için chrome.runtime.getURL():

content-script.js

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

Bir CSS dosyasında yazı tipleri veya resimler kullanmak istiyorsanız @@extension_id kullanarak aşağıdaki örnekte (content.css) gösterildiği gibi bir URL oluşturabilirsiniz:

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

Tüm öğeler, manifest.json dosyasında web'den erişilebilen kaynaklar olarak belirtilmelidir:

manifest.json

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

Güvende kalın

Yalıtılmış dünyalar bir koruma katmanı sağlasa da, içerik komut dosyalarını kullanmak ve web sayfasındaki güvenlik açıklarını düzeltmelidir. İçerik komut dosyası, ayrı bir web sitesi kullanıyorsanız (örneğin, fetch() yöntemini çağırarak) içeriklerinize göre filtreleme yaparken siteler arası komut dosyası çalıştırmadan önce gerçekleştirilen işlemleri. Yalnızca aşağıdaki amaçlarla HTTPS üzerinden iletişim kurun: &quot;man-in-the-middle&quot; saldırılarından kaçınmanızı öneririz.

Kötü amaçlı web sayfalarını filtrelediğinizden emin olun. Örneğin, aşağıdaki kalıplar tehlikelidir ve Manifest V3'te izin verilmiyor:

Yapılmaması gerekenler:

content-script.js

const data = document.getElementById("json-data");
// WARNING! Might be evaluating an evil script!
const parsed = eval("(" + data + ")");
Yapılmaması gerekenler:

content-script.js

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

Yapılması gerekenler

content-script.js

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

content-script.js

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