Mesaj iletme

İçerik komut dosyaları uzantı yerine bir web sayfası bağlamında çalıştığından genellikle biraz ve uzantının geri kalanıyla iletişim kurmanın bir yolunu sunar. Örneğin, bir RSS okuyucu uzantısı içerik komut dosyalarını kullanarak bir sayfada RSS özet akışının varlığını algılamasını, ardından arka plan sayfasını o sayfaya ilişkin bir sayfa işlemi simgesi görüntülemek için.

Uzantılar ve bunların içerik komut dosyaları arasındaki iletişim, mesaj iletme yöntemi kullanılarak yapılır. İkisinden biri Bu kullanıcı, karşı taraftan gelen mesajları dinleyebilir ve aynı kanalda yanıt verebilir. Bir mesaj geçerli herhangi bir JSON nesnesi (boş, boole, sayı, dize, dizi veya nesne) içermelidir. Çok basit bir Tek seferlik istekler için API ve uzun ömürlü olmanızı sağlayan daha karmaşık bir API bağlantıları kullanır. Ayrıca bir hafta içinde kimliğini biliyorsanız başka bir uzantıya gönderdiğiniz mesajı çapraz uzantı mesajlar bölümüne bakın.

Basit tek seferlik istekler

Uzantınızın başka bir kısmına tek bir mesaj göndermeniz (ve isteğe bağlı olarak yanıtı varsa) basitleştirilmiş runtime.sendMessage veya tabs.sendMessage kullanmanız gerekir . Bu , bir içerik komut dosyasından uzantıya (veya tam tersi şekilde) tek seferlik JSON seri çalıştırılabilir bir mesaj göndermenize olanak tanır . İsteğe bağlı bir geri çağırma parametresi, diğeri de kullanabilirsiniz.

İçerik komut dosyasından istek gönderme şu şekilde görünür:

chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
  console.log(response.farewell);
});

Uzantıdan bir içerik komut dosyasına istek göndermek, bunun hangi sekmeye gönderileceğini belirleyin. Bu örnekte, içerik komut dosyasına ileti gönderme gösterilmektedir tıklayın.

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
    console.log(response.farewell);
  });
});

Alıcı tarafta, şunları işlemek için bir runtime.onMessage etkinlik işleyicisi ayarlamanız gerekir: mesajını alırsınız. İçerik komut dosyası veya uzantı sayfasından da aynı görünür.

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello")
      sendResponse({farewell: "goodbye"});
  }
);

Yukarıdaki örnekte, sendResponse eşzamanlı olarak çağrılmıştır. Eşzamansız olarak kullanmak istiyorsanız sendResponse, onMessage etkinlik işleyicisine return true; ekleyin.

Not: onMessage etkinliklerini birden fazla sayfa dinliyorsa, belirli bir etkinlik için yalnızca sendResponse() işlevini çağıran ilk sayfa başarılı bir şekilde yanıt gönderir. Bu etkinliğe verilen diğer yanıtlar yoksayılır.
Not: sendResponse geri çağırması yalnızca eşzamanlı olarak kullanılıyorsa veya etkinlik işleyici eşzamansız olarak yanıt vereceğini belirtmek için true değerini döndürürse geçerlidir. Hiçbir işleyici doğru değerini döndürmezse veya sendResponse geri çağırması atık toplanmışsa sendMessage işlevinin geri çağırması otomatik olarak çağrılır.

Uzun ömürlü bağlantılar

Bazen tek bir istek ve yanıttan daha uzun süren bir görüşmenin olması fayda sağlar. Bu durumda, uzun ömürlü bir kanalı içerik komut dosyanızdan bir uzantı sayfasına açabilirsiniz veya Bunun tam tersi için de runtime.connect veya tabs.connect kullanın . Kanal, isteğe bağlı olarak, farklı bağlantı türlerini ayırt etmenize olanak tanıyan bir ada sahiptir.

Kullanım alanlarından biri otomatik form doldurma uzantısı olabilir. İçerik senaryosu, bir kanalı herkesin uzantı sayfasını ziyaret edin ve her giriş için uzantıya bir mesaj gönderin öğesine dokunun. Paylaşılan bağlantı, uzantının içerik komut dosyasından gelen çeşitli mesajlar arasında bağlantı oluşturmaya devam etmek için.

Bağlantı kurulurken her uç bir runtime.Port nesnesi verilir. Bu nesne ileti gönderip alabilirsiniz.

İçerik komut dosyasından kanal açma ve mesaj gönderip alma işlemlerini şu şekilde yapabilirsiniz:

var port = chrome.runtime.connect({name: "knockknock"});
port.postMessage({joke: "Knock knock"});
port.onMessage.addListener(function(msg) {
  if (msg.question == "Who's there?")
    port.postMessage({answer: "Madame"});
  else if (msg.question == "Madame who?")
    port.postMessage({answer: "Madame... Bovary"});
});

Uzantıdan bir içerik komut dosyasına istek göndermek, hangi sekmeye bağlanılacağını belirtir. Yukarıdaki örnekte verilen bağlantı çağrısını şununla değiştirin: tabs.connect.

Gelen bağlantıları işlemek için bir runtime.onConnect etkinliği oluşturmanız gerekir. dinleyicidir. İçerik komut dosyası veya uzantı sayfasından aynı görünür. Proje yöneticisinin uzantı "connect()" çağrısında bulunursa, kullanabileceğiniz runtime.Port nesnesiyle birlikte bu etkinlik tetiklenir bağlantı üzerinden ileti göndermek ve almak için kullanabilirsiniz. Yanıt vermek için yapmanız gerekenler gelen bağlantılar:

chrome.runtime.onConnect.addListener(function(port) {
  console.assert(port.name == "knockknock");
  port.onMessage.addListener(function(msg) {
    if (msg.joke == "Knock knock")
      port.postMessage({question: "Who's there?"});
    else if (msg.answer == "Madame")
      port.postMessage({question: "Madame who?"});
    else if (msg.answer == "Madame... Bovary")
      port.postMessage({question: "I don't get it."});
  });
});

Bağlantı noktası ömrü

Bağlantı noktaları, uzantının farklı bölümleri arasında iki yönlü bir iletişim yöntemi olarak tasarlanmıştır. Bağlantı noktaları, en küçük parça olarak kabul edilir. tabs.connect, runtime.connect veya runtime.connectNative, bir Port çağrıldıktan sonra ile başlar. Bu bağlantı noktası, diğer tarafa postMessage olarak değiştirin.

Bir sekmede birden fazla kare varsa tabs.connect çağrısı yapıldığında birden fazla çerçeve runtime.onConnect etkinliği (sekmedeki her kare için bir kez). Aynı şekilde runtime.connect kullanılırsa onConnect etkinliği birden çok kez tetiklenebilir ( çerçevesini kullanabilirsiniz.

Bir bağlantının ne zaman kesildiğini öğrenmek isteyebilirsiniz. Örneğin, durumu gösterir. Bunun için runtime.Port.onDisconnect etkinliğini dinleyebilirsiniz. Bu etkinliği, kanalın diğer tarafında geçerli bağlantı noktası olmadığında tetiklenir. Bu işlem şu durumlardan biri söz konusudur:

  • Diğer uçta runtime.onConnect için işleyici yok.
  • Bağlantı noktasını içeren sekme kaldırılır (ör. sekmede gezinilirse).
  • connect öğesinin çağrıldığı kare kaldırıldı.
  • Bağlantı noktasını alan tüm çerçeveler kaldırıldı (runtime.onConnect üzerinden).
  • runtime.Port.disconnect diğer uç tarafından çağrılır. connect aramasının sonuçlanması alıcının ucunda birden çok bağlantı noktasına takılır ve bu bağlantı noktalarının herhangi birinde disconnect() çağrılırsa onDisconnect etkinliği yalnızca gönderenin bağlantı noktasında tetiklenir; diğer bağlantı noktalarında tetiklenmez.

Çapraz uzantılar mesajlaşması

Uzantınızın farklı bileşenleri arasında mesaj göndermeye ek olarak, Messaging API'yi kullanabilirsiniz. Bu sayede, başkalarının kullandığı herkese açık bir API'yi bazı uzantılar var.

Gelen istekleri ve bağlantıları dinleme, dahili destek kaydına benzer. Tek fark, runtime.onMessageExternal veya runtime.onConnectExternal yöntemlerini kullanın. Elektronik tablo kullanarak yapılmış her:

// For simple requests:
chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.id == blocklistedExtension)
      return;  // don't allow this extension access
    else if (request.getTargetData)
      sendResponse({targetData: targetData});
    else if (request.activateLasers) {
      var success = activateLasers();
      sendResponse({activateLasers: success});
    }
  });

// For long-lived connections:
chrome.runtime.onConnectExternal.addListener(function(port) {
  port.onMessage.addListener(function(msg) {
    // See other examples for sample onMessage handlers.
  });
});

Benzer şekilde, başka bir uzantıya mesaj göndermek de uzantınızın içinden mesaj göndermeye benzer. Tek fark, iletişim kurmak istediğiniz uzantının kimliğini iletmeniz gerekmesidir. Örneğin:

// The ID of the extension we want to talk to.
var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(laserExtensionId, {getTargetData: true},
  function(response) {
    if (targetInRange(response.targetData))
      chrome.runtime.sendMessage(laserExtensionId, {activateLasers: true});
  }
);

// Start a long-running conversation:
var port = chrome.runtime.connect(laserExtensionId);
port.postMessage(...);

Web sayfalarından mesaj gönderme

Uzantılar arası mesajlaşmaya benzer şekilde, uygulamanız veya uzantınız normal web sayfalarından gelen iletiler. Bu özelliği kullanmak için önce manifest.json dosyanızda belirtmeniz gerekir. iletişim kurmak istediğiniz web sitelerini belirlemenize yardımcı olur. Örneğin:

"externally_connectable": {
  "matches": ["*://*.example.com/*"]
}

Bu işlem, belirttiğiniz URL kalıplarıyla eşleşen tüm sayfalarda mesajlaşma API'sini gösterir. URL kalıbı, en az bir ikinci düzey alan (yani "*", "*.com", "*.co.uk" ve "*.appspot.com" yasaktır. Web sayfasında şunu kullanın: runtime.sendMessage veya runtime.connect API'leri kullanarak belirli bir uygulamaya mesaj gönderebilir ya da uzantısına sahip olur. Örneğin:

// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
  function(response) {
    if (!response.success)
      handleError(url);
  });

Uygulama veya uzantınızda, web sayfalarından gelen mesajları şu uygulamayı kullanarak dinleyebilirsiniz: runtime.onMessageExternal veya runtime.onConnectExternal API'leri, cross-extension'a benzer. mesaj gönderin. Yalnızca web sayfası bağlantı başlatabilir. Örnek:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.url == blocklistedWebsite)
      return;  // don't allow this web page access
    if (request.openUrlInEditor)
      openUrl(request.openUrlInEditor);
  });

Yerel mesajlaşma

Uzantılar ve uygulamalar, yerel mesajlaşma ana makinesi. Bu özellik hakkında daha fazla bilgi edinmek için Yerel mesajlaşma bölümüne bakın.

Güvenlikle ilgili olarak göz önünde bulundurulması gerekenler

İçerik komut dosyaları daha az güvenilir

İçerik komut dosyaları, uzantı arka plan sayfasından daha az güvenilirdir (ör. kötü amaçlı bir web sayfası, içerik komut dosyalarının çalıştığı oluşturucu işleminin güvenliğini tehlikeye atabilir). Diyelim ki içerik komut dosyasından gelen mesajlar, bir saldırgan tarafından oluşturulmuş olabilir. Bu nedenle, dosyaların sağlandığından tüm girişleri temizleyin. İçerik komut dosyasına gönderilen tüm verilerin web sayfasına sızdırılabileceğini varsayın. İçerikten alınan iletiler tarafından tetiklenebilecek ayrıcalıklı işlemlerin kapsamını sınırlayın komut dosyaları.

Siteler arası komut dosyası çalıştırma

Bir içerik komut dosyasından veya başka bir uzantıdan ileti alırken siteler arası komut dosyası çalıştırmanın kurbanı olmamalıdır. Bu öneri, ve diğer web kaynaklarında çalışan içerik komut dosyalarının yanı sıra uzantı arka plan sayfasını da destekler. Özellikle aşağıdakiler gibi tehlikeli API'ler kullanmaktan kaçının:

chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // WARNING! Might be evaluating an evil script!
  var resp = eval("(" + response.farewell + ")");
});
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // WARNING! Might be injecting a malicious script!
  document.getElementById("resp").innerHTML = response.farewell;
});

Bunun yerine, komut dosyalarını çalıştırmayan daha güvenli API'leri tercih edin:

chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // JSON.parse does not evaluate the attacker's scripts.
  var resp = JSON.parse(response.farewell);
});
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
  // innerText does not let the attacker inject HTML elements.
  document.getElementById("resp").innerText = response.farewell;
});

Örnekler

Mesajlar yoluyla iletişimin basit örneklerini examples/api/mesajlar bölümünde bulabilirsiniz. dizin. Yerel mesajlaşma örneği, bir Chrome uygulamasının yerel uygulama Daha fazla örnek ve kaynak kodunun görüntülenmesiyle ilgili yardım için Örnekler bölümüne bakın.