İç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:
dom
i18n
storage
runtime.connect()
runtime.getManifest()
runtime.getURL()
runtime.id
runtime.onConnect
runtime.onMessage
runtime.sendMessage()
İç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 |
|
İ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ı:
- İçerik komut dosyalarını kaydedin.
- Kayıtlı içerik komut dosyalarının listesini alın.
- Kayıtlı içerik komut dosyalarının listesini güncelleyin.
- Kayıtlı içerik komut dosyalarını kaldırın.
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 birinclude_globs
kalıbıyla eşleşiyor. - URL, bir
exclude_matches
veyaexclude_globs
kalıbıyla da eşleşmiyor.matches
özelliği zorunlu olduğu içinexclude_matches
,include_globs
veexclude_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. |
İlgili çerçevelere ekle
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:
"man-in-the-middle" 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:
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);
Bunun yerine, komut dosyası çalıştırmayan daha güvenli API'leri tercih edin:
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);