记一次Ajax的跨站访问

近期,好久没更新博客了,好像开始赖起来了(有点觉得博客园的不支持markdown)

跨域, 为什么需要跨域?跨域有什么不好?怎么实现跨域?

自从上次面试以来,被问起Ajax怎么进行跨域访问没有答上来后,就像试试这个高大上的功能是怎么实现的呢,百度了一下好像也不是那么难

一、什么是跨域

 

只要协议、域名、端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作

在通常情况下,Ajax是不能跨站访问的,必须要遵守同源策略(same origin
policy).但是现在有了JSONP(JSON with
Padding),它用<script>标签来包装自己在不同的站点之间穿梭。

二、跨域会有什么问题?

 

防止CSRF攻击:

为什么要特别强调跨站访问这个问题,还是要说回安全性上来:

补充知识,什么是CSRF攻击?

–假如我点了一个有恶意脚本的链接(有可能藏在图片里面),这个脚本把我带进银行的某一个更改个人信息的页面。同时有可能我有这个银行的cookie,导致有可能就直接完成了

CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click
Attack”或者Session
Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

 

为什么会出现CSRF攻击?举例说明

完成这个功能要两方面来进行协商,就是说服务器端必须知道并且配合客户端的跨站点访问请求。

比如说有两个网站A和B。你是A网站的管理员,你在A网站有一个权限是删除用户,比如说这个过程只需用你的身份登陆并且POST数据到http://a.com/delUser,就可以实现删除操作。好现在说B网站,B网站被攻击了,别人种下了恶意代码,你点开的时候就会模拟跨域请求,如果是针对你,那么就可以模拟对A站的跨域请求,恰好这个时候你已经在A站登陆了。那么攻击者在B站内通过脚本,模拟一个用户删除操作是很简单的。面对这种问题,有从浏览器解决,但个人认为最好是从网站端解决,检测每次POST过来数据时热refer,添加accesstoken等都是好方法。

 

三、怎么实现跨域访问?

client-side:

1 document.domain + iframe

$.getJSON(<要请求的url>?callback=?, function(data){    //这里的callback=?,并不是真的传?过去,jquery会自己生成一串随机值替换这个?的       data=eval(data)                                                                   //这里就可以对收到的数据转化成object格式了       alert(data[1].title)                                                               //直接按属性访问   });

基于iframe实现的跨域要求两个域具有aa.xx.com,bb.xx.com这种特点,也就是两个页面必须属于一个基础域(例如都是xxx.com,或是xxx.com.cn),使用同一协议(例如都是
http)和同一端口(例如都是80),这样在两个页面中同时添加document.domain,就可以实现父页面调用子页面的函数,代码如下:

 

页面一在head内添加js如下:

 

document.domain = “xx.com”;

server-side:

function aa(){

先要收到callback传来的值,这里记作jsonp(类似的格式可能是这样”jsonp47981231933”)

alert(“p”);

再来准备返回数据了,比如要返回的数据类似于[{“id”:1,”title”:”aa”},{“id”:2,”title”:”bb”}]

}

那么要配合一个跨站访问,必须要对原有返回数据进行一次包装成:

body添加iframe和js如下

jsonp([{“id”:1,”title”:”aa”},{“id”:2,”title”:”bb”}])

iframe
src=”http://localhost:8080/CmsUI/2.html
id=”i”

 

document.getElementById(‘i’).onload = function(){

 

var d = document.getElementById(‘i’).contentWindow;

463.com,Note:
上面的callback是可以自己换成其他名字的,我感觉这个属性像是一个密钥一样,只有知道服务器端到底接受什么名字的密钥才能进行通信

d.a();

 

};

$.getJSON(<要请求的url>?anything=?, function(data){        data=eval(data)                                                                          alert(data[1].title)                                                                  });

页面二 head添加如下

 

document.domain = “xx.com”;

 

function a(){


alert(“c”);

}

这时候父页面就可以调用子页面的a函数,实现js跨域访问

2 Jsonp

利用script标签没有跨域限制的“漏洞”(历史遗迹啊)来达到与第三方通讯的目的。当需要通讯时,本站脚本创建一个script元素,地址指向第三方的API网址,形如:script
src=”http://www.example.net/api?param1=1¶m2=2″>

相关文章