专栏首页一个会写诗的程序员的博客在浏览器扩展程序中进行: 跨域 XMLHttpRequest 请求

在浏览器扩展程序中进行: 跨域 XMLHttpRequest 请求

跨域 XMLHttpRequest 请求 https://crxdoc-zh.appspot.com/extensions/xhr

普通网页能够使用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的资源(假设该扩展不是来自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 xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // 警告! 这里有可能执行了一段恶意脚本!
    var resp = eval("(" + xhr.responseText + ")");
    ...
  }
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // 警告! 这样处理有可能被注入恶意脚本!
    document.getElementById("resp").innerHTML = xhr.responseText;
    ...
  }
}
xhr.send();

实际上我们应该首选不会执行脚本的安全API:

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // JSON解析器不会执行攻击者设计的脚本.
    var resp = JSON.parse(xhr.responseText);
  }
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // innerText不会给攻击者注入HTML元素的机会.
    document.getElementById("resp").innerText = xhr.responseText;
  }
}
xhr.send();

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在 selenium IDE 插件中添加上传云端平台的功能

    一个会写诗的程序员
  • React.js 集成 Spring Boot 开发 Web 应用

    使用文档: https://nowa-webpack.github.io/nowa/

    一个会写诗的程序员
  • Spring Boot 自定義 HttpMessageConverter 解決 String 類型返回JSON對象問題

    HttpMessageConverter 接口介绍 org.springframework.http.converter.HttpMessageConvert...

    一个会写诗的程序员
  • XMLHttpRequest

    愤怒的小鸟
  • 你真的会使用XMLHttpRequest吗?

    我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是属于不同维度的2个概念。

    用户2458785
  • XMLHttpRequest使用指南大全

    我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是属于不同维度的2个概念。

    空空云
  • JavaScript学习笔记028-ajax0get0post0跨域请求

    Mr. 柳上原
  • Web前端-Ajax基础技术(上)

    ajax是浏览器提供一套的api,用于向服务器发出请求,接受服务端返回的响应,通过javascript调用,实现通过代码控制请求与响应,实现网络编程。

    达达前端
  • Ajax之路

    第一部分: Ajax全称Asynchronous Javascript and XML,中文意思为“异步的Javascript 和XML”。 Ajax这组技术...

    用户1149564
  • Ajax与Comet

    Ajax(Asynchronous JavaScript + XML的简写)可以向服务器请求数据而无需卸载(刷新)页面,带来更好的用户体验。 Ajax技术的...

    奋飛

扫码关注云+社区

领取腾讯云代金券