再也不学AJAX了!(三)跨域获取资源 ① - 同源策略

我们之前提到过,AJAX技术使开发者能够专注于互联网中数据的传输,而不再拘泥于数据传输的载体。通过AJAX技术,我们获取数据的方式变得更加灵活,可控和优雅。

但是AJAX技术并不是一把万能钥匙,互联网中的数据隐私和数据安全(例如你的银行账号和密码)也非常重要,为了保护某些用户数据的隐私与安全,浏览器使用“同源策略”限制了AJAX技术获取数据的范围和能力。但在一些合理的场景中,我们又不得不想办法绕过同源策略,实现跨域请求资源。因此“跨域技术”一直成为开发者们经久不衰的讨论话题。

在“跨域获取资源”这一主题中,我们将围绕“同源策略”和“跨域”两大主题展开,不但讲述它们是什么,更说明了为什么要这么做。相信你在读完该主题下的两篇文章后,一定会对这两大主题有一个清晰,系统的认识。

需要提前声明的是,本主题下的文章并不会像众多相同主题的文章一样罗列出所有的跨域技术,而只会捡最主流的四种进行讲解。因为我并不打算写“教你如何跨域”这样类型的文章。

让我们开始吧。

同源策略

整个互联网世界的数据要么存储在服务端(即服务器,如数据库,硬盘等)中,要么存储在客户端(即浏览器,如cookie,LocalStorage,sessionStorage)中。互联网数据的传输实际上就是客户端与服务端之间的交互。

而所谓的数据隐私与安全保护,说白了就是数据拥有者对数据索取者发出警告:“不是你的你别动”。

搞清了这个原则,我们就很容易明白,如果你在客户端,并且想要获取服务端数据,你首先需要通过服务器端的验证,证明你有权限获取数据(例如“登录”),而如果你在服务端,想要获取客户端的某些数据,你同样需要客户端通过某些方式验证你有资格获取相应的数据资源。

那么上面提到的“某些方式”是什么呢?其中最重要的就是我们今天的主题之一 -- 浏览器的“同源策略”。

浏览器的“同源策略”

浏览器所遵守的“同源策略”是指:限制不同源之间执行特定操作。这涉及到两个问题:什么是“”?,以及“特定操作”是指什么?

让我们停下来解释一下这个概念:

  1. 一个协议域名端口三部分组成,这三者任一一个不同都会被浏览器识别为不同的源;
  2. 上文所提到的特定操作是指:
    • 读取 Cookie,LocalStorage 和 IndexDB;
    • 获取 DOM 元素;
    • 发送 AJAX 请求;

在搞清了同源策略的概念之后,让我们看看浏览器是出于怎样的考虑,一直坚守着同源策略:

为什么要有“源”的概念?

因为不同的源,大多数情况下就意味着它们在互联网中归属于不同的站点(或是被用作不同的用途)。也就是说它们是不同的项目,有不同的文件根目录,那么它们的数据也不应该共享也就理所应当了,否则数据的隐私和安全也无从谈起。不过请注意,我上面所说的话是基于“不同源就彼此不相干”的假设,这其实存在一些问题,我们之后会提到。

为什么不能执行“特定操作”?

这个需要我们假设,如果我们想做一些“坏事”,并且浏览器允许我们执行这些“特定操作”,我们作为“坏人”能做什么:

首先,由于很多网站使用浏览器存储用户的用户名和密码,那么我们便可以在A域中(我们在服务器上托管的网站)读取任意来访用户的所有Cookie信息(没有同源策略的保护,该用户所有网站的Cookie记录都是透明的),我们就可以利用这些Cookie信息伪装成来访用户做任何事,而在现实世界,出于同源政策的保护,我们只能访问用户该域下的Cookie信息,也就是说,我们只能访问我们自己设置的Cookie信息。

其次,如果我们能够获取不同域下的DOM元素,我们就可以通过