跨域请求

跨域请求 XMLHttpRequest

普通网页能够使用XMLHttpRequest对象发送或者接受服务器数据,但是它们受限于同源策略。扩展可以不受该限制。任何扩展只要它先获取了跨域请求许可,就可以进行跨域请求。

注意:页面内容脚本不能直接发起跨域请求。然而,任何一个页面内容脚本都可以发送消息给父扩展,请求父扩展发起一次跨域请求。关于使用这一技术的例子,请参照contentscript_xhr example


扩展所属域

每个正在运行的扩展都存在于自己独立的安全域里。默认情况下,扩展只能使用XMLHttpRequest获取自己所属域里的资源。例如,扩展包含一个叫config.json的JSON文件,该文件位于config_resources目录,那么该扩展能够使用下面这段代码获取文件内容:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
xhr.open("GET", chrome.extension.getURL('/config_resources/config.json'), true);
xhr.send();

但如果扩展希望访问自己所属域以外的资源,比如来自http://www.google.com的资源,浏览器就不会允许这样的请求,除非该扩展获得了相应的跨域请求允许。


获取跨域请求允许

通过添加域名或者域名匹配到manifest文件的permissions段,该扩展就拥有了访问除了自己所属域以外的其他域的访问权限。

{
  "name": "My extension",
  ...
  "permissions": [
    "http://www.google.com/"
  ],
  ...
}

跨域允许设置可以使用完整域名,例如:

  • “http://www.google.com/”
  • “http://www.gmail.com/”

或者使用模式匹配,例如:

  • “http://*.google.com/”
  • “http://*/”

模式匹配“http://*/” 表示可以发起到所有域的HTTP请求。注意在这里,模式匹配有点像内容脚本匹配,但是这里的任何域名后的路径信息都被忽略

这里还需要注意访问权限是根据访问协议(匹配模式里的http或者https或者其他协议名)及域名来授予的。例如某个扩展希望同时基于https和http协议访问某个域或者某些域,那么它必须分别获取基于这两种协议的访问允许(类似下面这样的声明):

"permissions": [
  "http://www.google.com/",
  "https://www.google.com/"
]


安全性考虑

当通过XMLHttpRequest获取资源时,你编写的背景页需要注意不要成为跨域脚本的牺牲品。特别注意避免使用像下面这样的危险API来处理响应结果:

// 警告! 这里有可能执行了一段恶意脚本!
var resp = eval("(" + xhr.responseText + ")");

// 警告! 这样处理有可能被注入恶意脚本!
document.getElementById("resp").innerHTML = xhr.responseText;

应该使用如下代码:

// JSON解析器不会执行攻击者设计的脚本.
var resp = JSON.parse(xhr.responseText);
// innerText不会给攻击者注入HTML元素的机会.
document.getElementById("resp").innerText = xhr.responseText;

另外在使用通过协议HTTP获取的资源时要特别小心。如果你开发的扩展被应用在恶意网络环境中,网络攻击者(又叫 "中间人攻击") 可能篡改服务器响应内容从而可能攻击你编写的扩展。事实上,你应该尽可能地首选使用HTTPS协议。




举报

© 著作权归作者所有


0