在解决问题之前,我们需要知道什么是跨域,为什么会产生跨域
跨域:
跨域种类:
1.域名不同
2.域名相同,端口不同
3.ip不同
4.ip不同,端口不同
跨域源自js的安全机制
跨域例子:
Access to XMLHttpRequest at 'http://localhost:8083/category.json' from origin 'http://localhost:8082' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
解决跨域的问题:
1.使用jsonp来解决跨域的问题,在js中不能够跨域访问数据,但是在js中可以跨域请求js片段(js代码)
2.所以我们可以把数据包装成js片段,这样就跨域获取到我们想要的数据。
3.可以使用ajax请求包含json数据的js片段,然后在回调访问内立即执行响应的js片段,从而取出包含在内的json数据
jsonp的原理:通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入,有种回调的味道!需要注意的是 jsonp是一种非官方的跨域请求协议,而ajax只是一种请求的方式。二者不可相提并论!
Jsonp实例解读
1.较为原始的方式
//本地服务器下存在如下代码
<!DOCTYPE>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="http://diffReSource/remote.js"></script>
</head>
<body>
</body>
</html>
//远程(非同源)服务器下存在如下remote.js文件
alert("hello bro");
那么我么在运行本地服务器下的代码是,<script>标签会跨域加载到远程服务器上的js文件,页面发生弹窗显示 "hello bro",这边是最基本的jsonp,即<script>标签允许跨源获取数据
2.进阶jsonp
使用js函数返回数据,并且在本地读取
//本地服务器下存在如下代码
<!DOCTYPE>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
function testDemo(data){
alert("Hello"+ data.name);
}
</script>
<script type="text/javascript" src="http://diffResource/remote.js"></script>
</head>
<body>
</body>
</html>
//远程(非同源)服务器下存在如下remote.js文件
testDemo({"name":"hubery"});
3.动态生成js脚本
//本地服务器下存在如下代码
<!DOCTYPE>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
function jsonpCall(data){
alert("Hello"+ data.name);
}
var url="http://diffResource/testUrl?callback="+"testDemo";
var script=document.createElement('script');
script.setAttribute('src', url);
//插入js脚本
document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>
<body>
</body>
</html>
//远程(非同源)服务器下存在如下remote.js文件
testDemo({"name":"hubery"});
其实如果有需要的话我们可以对上面的跨域请求进行进一步的封装。
4.Jquery之jsonp
//本地服务器下存在如下代码
<!DOCTYPE>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Test</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
$.ajax({
type: "get",
async: false,
url: "http://remoteServer/jsonp/testDemo",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"testDemo",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(data){
alert("Hello"+data.name);
},
error: function(){
alert('something error');
}
});
});
</script>
</head>
<body>
</body>
</html>
//远程(非同源)服务器下存在如下/testDemo请求并且返回如下json数据
{"name":"hubery"}
其实凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>
//另外关于何时调用success和error方法
1、statusCode是2xx时,会执行success回调函数;
2、statusCode是304时,会执行success回调函数;
3、statusCode为其他值,则会执行error回调函数;
4、datatype如果是json,而转换成json出错时会调用error回调函数。