跨域问题

首先先解释名词: 

同源策略,浏览器的一种安全策略,只有域名协议端口完全一直才能访问。

http://www.liuyixiang.cn:80/a.html

协议         域名         端口

为什么会有这种策略呢?

大家看下下面的代码:

<iframe src="http:jd.com" frameborder="0"></iframe>
<script>
 // 接下来,我们在本地添加一些操作,是不是就能获取相关私密信息了?
</script>

所以,处于安全的考虑,浏览器是不支持我们跨域访问其它页面的对象的。

也就是说:

1. 不允许跨域操作不同域的dom,(包括cookie)

2. 不允许跨域Ajax

可是在很多情况下,我们是需要跨域访问相关数据的,比如一个网站很大,比如说qq:

v.qq.com / email.qq.com ,不同域之间也要访问数据,该怎么办呢?


目前给大家解释三种解决办法:

1.代理服务器(后台技术,这里不作解释)

2.JSONP 

3.document.domain 和 iframe 


接下来就给大家介绍下document.domain 和iframe 是如何实现跨域的


//此方法解决跨域问题要求一级域名一致
//步骤:
//1. 首先要在不同域的两个文档里都设置:document.domain = 'liuyixiang.cn'
//2. 在父窗口中创建iframe,并将它隐藏


//假设路径是: http://blog.liuyixiang.cn/son.html
<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<p id="p1">需要被跨域访问的数据</p>
	<script type="text/javascript">	
	document.domain = 'liuyixiang.cn';
	</script>
</body>
</html>



//假设路径是: http://liuyixiang.cn/father.html
<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	
	<script type="text/javascript">
		document.domain = 'liuyixiang.cn';
		var iframe = document.createElement('iframe');
		ifram.src = 'http://blog.liuyixiang.cn/son.html';
		ifram.style.display = 'none';
		document.body.appendChild(iframe);
		iframe.onload = function(){
			var doc = iframe.contentWindow.document || iframe.contentDocument;
			// 这里就可以操作son.html了
			// 比如说我们改变下字体颜色
			doc.getElementById("p1").style.color = 'red';

			// 当然,如果我们想操作father.html 就直接document
			iframe.onload = null;
		}
	</script>
	
</body>
</html>

接下来在给大家介绍下jsonp是如何实现跨域的:(会有点难哦,需要懂一点点后台语言)

先来讲下jsonp的跨域原理:

实际上是利用JavaScript标签具有可跨域性的特点,由服务端返回一个预先定义好的JavaScript函数的调用,并将服务端数据以该函数参数的形式传递过来,此方法需要前后端配合来实现完成。

先来解释下JavaScript标签具有可跨域性的原因,我们写一个html文档需要jQuery框架时,引用别人写好的JQuery的CND,有没有想过跨域问题,哈哈,因为浏览器没有管,所以,JavaScript标签是具有可跨域性的,但我们导入JavaScript 时,src的后缀名并不能代表什么,关键是看服务器返回的文本内容,比如一个js文件也可以用.php结尾,只要我们指定了它的Content-type:text/javascrip,告诉浏览器返回的是JavaScript。如果返回的是一个事先声明好的函数调用,那么在这个函数调用过程中,将跨域请求的数据以实参传递过来,一般是json格式。

所以结合src的可跨域性和Content-type指定文档类型两个方面,就可以实现跨域了。

JSONP的本质就是服务端返回一个JavaScript函数调用,而这个函数事先已经本声明了。 有没有晕啊?2333把基本语法写出来大家瞧下

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	
	<script type="text/javascript">
		function jsonp(data){
			//此处的data为跨域获得的数据,拿来就可以直接用了
		}
	</script>

	<!--接下来是一个跨域请求,并传递参数-->
	<!--
		此处简单给大家介绍下后台代码:伪码说明下
		首先后台先获取callback参数,然后执行
		执行的时候,会把后台跨域需要访问的数据当作实际参数传入
	-->
	<script type="text/javascript" src="http://liuyixiang.cn/service.php?callback=jsonp"></script>
	<!--
		这样呢,用JavaScript实现就完成了
	-->
</body>
</html>
注意:通过jsonp跨域请求只能用get方法,因为我们可以看到请求参数就在url中

接下来,介绍下在JQuery中如何Ajax实现跨域访问:

先介绍下Ajax请求的两种用法:

1.发起XMLHttpRequest

2.跨域访问

之前,我们已经介绍了在Jquey中如何运用Ajax,也就是第一种,现在我们来介绍下第二种

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<!--首先肯定是要导入jQuery了233-->
	<script type="text/javascript" src="jquery.min.js"></script>
	
	<script type="text/javascript">

		$.ajax({
			type:'post',
			url:'htttp://liuyixiang.cn/service.php',
			dataType:'jsonp', // 注意此属性为跨域访问的关键属性
			// 解释:
			// 当我们设置dataType:'jsonp'后,Ajax内部就不会再创建 XMLHttpRequest对象
			// 而是在head中创建script元素,并自动设置属性src = url?callback=jsonp(随机生成)
			// 来模拟之前js的写法
			jsonp:'callback',//指定服务器端接受参数key的名称,默认为callback,此处要是更改,后台也要变化
			jsonpCallback:'test',// 指定回调函数,默认会自动生成,test是预先定义好的函数,需要我们自己写。
			// 一般情况下,最后这两种属性都不需要设置
			success:function(data){
				// data即为服务端传来的数据了
			}
		});
	</script>

</body>
</html>

上面就是用Ajax 来实现跨域,接下来我们写一个小例子来看下:

ak是错的,大家不用试了,我们来调用下百度天气服务的PAI,只是一个用Ajax实现跨域的例子

	<script type="text/javascript">

	$.ajax({
		type:"get",
		url:'http://api.map.baidu.com/telematics/v3/weather',
		dataType:'jsonp',
		data:{
			ak:'3L8K8EZ4NxUQ4QzxpI74cL3VCZzIX3ur',
			location:'北京',
			output:'json',
		},
		success:function(info){
			// ..操作就行
		}
	});

	</script>


请求参数:

data{

ak:'..',

location:'北京',

}

会自动处理的,


当我们把返回结果设置为json时,通过success:function(data){},data 即为我们要处理的json对象了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值