[聚合文章] 理解跨域问题及如何解决

JSONP 2016-03-11 14 阅读

什么是跨域?

简单的来说,出于安全方面的考虑,javascript不能访问其他服务器上的内容,即“同源策略”( 参考1参考2 )。跨域就是通过某种手段绕过同源策略去访问不同服务器上的内容。 只要域名、端口、协议任何一个不同,就是不同的域。协议或端口不同只能通过后端来解决。

URL                   说明        是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夹 允许
http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许
http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同协议 不允许
http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许
http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允许
http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许

解决跨域问题的方案有很多,最流行的就是jsonp了,但是jsonp只能解决域名不同造成的跨域,端口、协议不同的跨域可以通过后端方案解决。下面分析下各种解决方案吧。

前端解决方案

1、jsonp2、iframe

后端解决方案

1、Access-Contrl-Allow-Origin

2、apache转发

3、CORS跨域资源共享

JSONP

JSONP是什么?

JSON(Javascript Object Notation)是一种轻量级数据格式,JSONP(Json for padding)是JSON 的一种“使用模式”,可以让网页从别的网域要资料。JSONP也叫填充式JSON,是应用JSON的一种新方法,只不过是被包含在函数调用中的JSON,例如:

callback({a:'b'});

JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。

JSONP跨域原理

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。

img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。

在jQuery中使用JSONP获取跨域数据

jQuery代码

$(document).ready(function(){
    $.ajax({
	url : 'http://b.test:8080/jsonp.php',
	type : 'post',
	dataType : 'jsonp',
	jsonpCallback: 'hehe',
	success : function (data) {
	    alert(data.a);
	},
	error : function(data) {}
    });
});

1、url 中不用指定 callback 参数。对于 jQuery 中的 jsonp 来说,callback 参数是自动添加的

2、默认情况下,jQuery 生成的 jsonp 请求中 callback 参数是形如 callback=jQuery180099599698651582_1393992892572 这种根据看似随机的名字,对应的就是 success 那个处理函数,所以一般不用特意处理。

3、如果响应内容中是写死了 callback 名的话,那么可以对 jQuery 的 jsonp 指定 callback 名。

PHP代码

$jsondata = json_encode(array(‘a’ => ‘b’));

$callback = $_REQUEST[‘callback’];

echo “(function(){var _jsonData=$jsondata; $callback(_jsonData);})()”;

[/pre]

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。