首页 > 代码库 > 深入剖析jsonp跨域原理

深入剖析jsonp跨域原理

在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域的原理。搞明白了一些以前不是很懂的地方,比如:

1)为什么jsonp跨域只能是get请求,而不能是post请求;

2)jsonp跨域的原理到底是什么魔法;

3)除了jsonp跨域之外还有那些方法绕过“同源策略”,实现跨域访问;

4)jsonp和ajax,或者说jsonp和XMLHttpRequest是什么关系;

等等。

1.同源策略

说到跨域,首先要明白“同源策略”。同源是指:js脚本只能访问或者请求相同协议,相同domain(网址/ip),相同端口的页面。

我们知道,js脚本可以访问所在页面的所有元素。通过ajax技术,js也可以访问同一协议,同一个domain(ip),同一端口的服务器上的其他页面,请求到浏览器端之后,利用js就可以进行任意的访问。但是对于协议不同, 或者domain不同或者端口不同的服务器上的页面就无能为力了,完全不能进行请求。

下面在本地搭建两个tomcat,分别将端口设为8080,和8888,进行相关实验。显然他们的端口是不同的。演示如下:

http://localhost:8888/html4/ajax.html的代码如下:

<!doctype html><html><head>	<meta charset="utf-8">	<meta name="keywords" content="jsonp">	<meta name="description" content="jsonp">	<title>jsonp</title>	<style type="text/css">		*{margin:0;padding:0;}		a{display:inline-block;margin:50px 50px;}	</style></head><body>	<a href="javascript:;" onclick="myAjax();">click me</a>	<script type="text/javascript" src="http://www.mamicode.com/js/jquery-1.11.1.min.js"></script><script type="text/javascript">function myAjax(){	var xmlhttp;	if(window.XMLHttpRequest){		xmlhttp = new XMLHttpRequest();	}else{		xmlhttp = ActionXObject("Microsoft.XMLHTTP");	}		xmlhttp.onreadystatechange = function(){		if (xmlhttp.readyState==4 && xmlhttp.status==200){			console.log(xmlhttp.responseText);					}  	}	var url = "http://localhost:8080/minisns/json.jsp" + "?r=" + Math.random();	xmlhttp.open("Get", url, true);	xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");	xmlhttp.send();	}</script></body></html>

这里为了结果不收其他js库的干扰,使用了原生的XMLHttpRequest来处理,结果如下:

我们看到8080端口的js的ajax请求无法访问8888端口的页面。原因是“同源策略不允许读取”。

既然普通的ajax不能访问,那么怎样才能访问呢?大家都知道,使用jsonp啊,那jsonp的原理是什么呢?他为什么能跨域呢?

2.jsonp跨域的原理

 

深入剖析jsonp跨域原理