在项目中遇到一个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="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跨域的原理
时间: 2024-10-08 13:13:01