跨域
跨域简单的说就是浏览器处于安全方面的考虑,基于浏览器的同源策略,不允许不同域之间相互请求资源…
背景
- Ajax只能够在同域下请求资源(ajax只能提交json,xml,text,html等文件类型的数据,如果二进制文件就需要使用formData)
- web页面上调用js文件时,不受是否跨域的影响(jsonp)
同源策略

当 协议,子域名,主域名,端口中任意一个不相同时,就是不同域的,那么这两个域需要交互,就是跨域的:
同源策略的限制包括:
- 不能Ajax(同源数据请求方式)
- 不能操作dom
- 不能共享Cookie、LocalStorage、IndexedDB 等存储性内容
但是有三个标签是允许跨域加载资源
1 | <img src=XXX> |
跨域需求
一般进行跨域,都是基于两种需求:
- 1.跨域数据通信(简单的说就是共享数据或者数据传递)
- 2.跨域获取dom (例如获取iframe的高度)
JSONP(跨域获取数据)
- 为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP;缺点是仅支持
get方法具有局限性。 - 利用
<script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据 - JSONP请求一定需要对方的服务器做支持才可以
- 该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
总结
jsonp就是利用script标签可以不受浏览器同源策略的限制,通过get的方式跨域进行数据通信的方式,目前兼容型较好,但是只能支持get请求;目前jqery进行了封装
1.基本使用
在客户端1
2
3
4
5
6
7
8
9<script>
# 客户端根据指定的callback函数,定义对返回数据data的操作,例如alert出data的result属性
someCallBack(data){
// todo with data
alert(data.result);
}
</script>
# 在script标签中引入跨域请求的url,必须指定callback给一个函数(必须),也可以传入其他参数(非必须)
<script src="www.crossDomainServer.com/remote.js?callback='someCallBack'&userName='unclePis'"></script>
在服务器端,只需要使用传入的函数将需要返回的json数据包裹返回就好,例如
1 | someCallBack({name:'root',password:'1233211234567'}) |
这样在客户端就相当于加载了一个js文件,调用定义好的函数
1 | <script> |
2.动态添加
1 | var someCallBack = function(data){ |
3.jQuery的jsonp形式
简单的说,jquery的dataType为jsonp的时候,就帮你封装了上面的基本实现,你只需要在success里面处理数据的返回就ok了,感觉好像ajax在同域请求资源一样1
2
3
4
5
6
7
8
9
10
11
12$.ajax({
url:"http://crossdomain.com/jsonServerResponse",
dataType:"jsonp",
type:"get", # 可以省略,JSONP都是GET
jsonpCallback:"fn",# ->自定义传递给服务器的函数名,而不是使用jQuery自动生成的,可省略
jsonp:"jsonp",# ->把传递函数名的那个形参callback变为jsonp,可省略
success:function (data){
console.log(data);}
}),
error: function(){
alert('fail');
}
JSONP和AJAX对比
- JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式
- 但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)
其他
跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。