在一次工作中,遇到了需要跨域访问的需求,于是研究了这方面的技术。先来介绍下我的应用场景,我们有一台服务器A在www.A.com,另一台服务器B在www.B.com,如果请求A的页面后,在该页面写一段JS使用AJAX访问B服务器,浏览器会拒绝这次请求。这是现代浏览器遵循的同源策略。
1同源策略
同源策略由Netscape提出,又名同域策略是浏览器中的主要安全措施。这里的“源”指的是主机名、协议和端口号的组合;我们可以把一个“源”看作是某个web页面或浏览器所浏览的信息的创建者。同源策略,简单地说就是要求动态内容(例如,JavaScript或者VBScript)只能阅读与之同源的那些HTTP应答和cookies,而不能阅读来自不同源的内容。更为有趣的是,同源策略对写操作没有任何限制。因而,一个web站点可以向任何其他的Web站点发送(或写入)HTTP请求,尽管为了防止跨站请求可能会对发送这些请求有关的cookies和头部有所限制。
2能访问异域的标签
通过日常的开发经验,我们可以得知。类似于<a>、<iframe>、<script>等带有src的标签,都可以跨域访问。那我们能不能通过加载一个js来获取异域服务器的信息呢?
如是,我就在B服务器上写了一段js,如下所示:
alert("你好,我是B服务器!");
然后使用<script>在A的HTML中引用B的JS文件。显然,我访问A服务器的HTML后得到了我想要的结果,浏览器弹出了"你好,我是B服务器!"的对话框。如是,我开始思考,这段JS能不能动态生成,并且能够携带B服务器查询的数据回客户端,然后触发A页面中的回调函数呢?
如是,我将<script>标签的src属性指向了我的Servlet(Java Web开发组件),Servlet执行服务器操作后返回一段JS给客户端,代码如下:
// 调用业务组件执行业务,然后返回执行成功的数据,这里只简单的返回一个JSON对象
response.write("callback({\"success\":true})")
这段JS很明显,会给客户端返回一个回调函数callback并传入了一个JSON对象。客户端页面可以定义该callback函数,就可以执行回调操作。此时就可以完美解决浏览器的同源策略问题。
3其它前端框架同源策略的解决方案
因为此类需求频繁出现,业界也提出了一个新的名词JSONP(JSON with Padding,P是填充的意思)。JSONP是JSON的一种使用形式。