专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Web前端

一次容易的请求

发布时间:2010-05-20 14:01:29 文章来源:www.iduyao.cn 采编人员:星星草
<script language="javascript">c_a_3();</script>
一次简单的请求
如果你仅仅需要给你自己的扩展的另外一部分发送一个消息(可选的是否得到答复),你可以使用简单的chrome.extension.sendRequest()或者chrome.tabs.sendRequest()方法。这个方法可以帮助你传送一次JSON序列化消息从content script到扩展,反之亦然。如果接受消息的一方存在的话,可选的回调参数允许处理传回来的消息。
像下面这个例子一样,可以从content script 发起一个请求:
contentscript.js
================
chrome.extension.sendRequest({greeting: "hello"}, function(response) {
  console.log(response.farewell);
});
传递一个请求到扩展很容易,你需要指定哪个标签发起这个请求。下面这个例子展示了如何指定标签发起一个请求。
background.html
===============
chrome.tabs.getSelected(null, function(tab) {
  chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
    console.log(response.farewell);
  });
});
接受消息的一方,需要启动一个chrome.extension.onRequest事件监听器用来处理消息。这个方法在content script和扩展中都是一样的。这个请求将会保留直到你做出了回应。下面的这个例子是一个很好的做法调用一个空对象请求然后得到答复的例子。
chrome.extension.onRequest.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"});
    else
      sendResponse({}); // snub them.
  });
小提示:如果多个页面都发起了相同的请求,都在等待答复,只有第一个发起请求的页面会得到响应,其他的将会被忽略。
长时间的保持连接
有时候持续长时间的保持会话会比一次简单的请求有用。你可以建立一个长时间存在的通道从content script到扩展, 反之亦然,使用chrome.extension.connect()或者chrome.tabs.connect()方法,你可以把这个通道命名,为了更方便区分不同类型的连接。
一个有用的例子就是自动填写表单扩展。content script可以建立一个通道在登录页面和扩展之间,同时发出一条消息给扩展,告诉扩展需要填写的内容。共享的连接允许扩展保持共享状态,从而连接几个来自content script.的消息。
当建立连接,两端都有一个Port 对象通过这个连接发送和接收消息。
下面展示了如何从content script建立一个通道,发送和接受消息:
contentscript.js
================
var port = chrome.extension.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"});
});
从扩展到content script发送一个请求看起来非常简单,除了你需要指定哪个标签需要连接, 简单的办法就是上面例子中的chrome.tabs.connect(tabId, {name: "knockknock"}).
为了处理正在等待的连接,你需要用chrome.extension.onConnect 事件监听器,对于content script或者扩展页面,这个方法都是一样的,但你的扩展的另外一个部分调用"connect()", 这个事件一旦被触发,通过这个连接你可以利用Port对象进行发送和接收消息,下面的例子展示了如何处理连接:
chrome.extension.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."});
  });
});
你可能想知道这个连接什么时候被关闭。例如,如果你在为每个开放的端口维护分开的状态,如果你想知道它什么时候关闭,因此,需要监听Port.onDisconnect 事件,这个事件被激发,要么是通道调用了Port.disconnect()这个方法,要么这个页面包含的端口没有被加载(例如这个标签是个导航栏) ,onDisconnect()保证仅仅被激发一次。
扩展之间的消息传递
除了在扩展的组件之间传送消息,你还可以使用消息API来和其他的扩展之间进行通信,你可以使用一个其他扩展也可以利用的公共API。
对于扩展内部来说,监听一个传入的请求和连接是一样的,你可以使用chrome.extension.onRequestExternal或者chrome.extension.onConnectExternal方法,如下面的例子所示:
// For simple requests:
chrome.extension.onRequestExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.id == blacklistedExtension)
      sendResponse({});  // 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.extension.onConnectExternal.addListener(function(port) {
  port.onMessage.addListener(function(msg) {
    // See other examples for sample onMessage handlers.
  });
});
同样,传递一个消息到另外一个扩展和把消息传递给自己扩展的另外一部分是一样的,唯一不同的是你必须知道你要传给消息的扩展的ID例如:
// The ID of the extension we want to talk to.
var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

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

// Start a long-running conversation:
var port = chrome.extension.connect(laserExtensionId);
port.postMessage(...);
安全策略
无论是从content script还是从扩展接收消息,你的页面不应该cross-site scripting,特别是避免使用那些不安全的API例如下面的例子:
background.html
===============
chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
  // WARNING! Might be evaluating an evil script!
  var resp = eval("(" + response.farewell + ")");
});

background.html
===============
chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
  // WARNING! Might be injecting a malicious script!
  document.getElementById("resp").innerHTML = response.farewell;
});
相反的,选择更安全的API而不是运行脚本。
background.html
===============
chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
  // JSON.parse does not evaluate the attacker's scripts.
  var resp = JSON.parse(response.farewell);
});

background.html
===============
chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
  // innerText does not let the attacker inject HTML elements.
  document.getElementById("resp").innerText = response.farewell;
});
范例
你可以在这个examples/api/messaging 目录下找到消息传递的例子,也可以找到contentscript_xhr (contents script和扩展之间传递消息的例子),更多的内容和源码,请查看Smples.
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: