1、首先一个域名的组成:
当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域
JavaScript出于安全方面的考虑,不允许跨域调用其它页面的对象。跨域就可以理解为因为JavaScript同源策略的限制,a.com下的js无法操作b.com或者c.a.com域名下的对象。
2、处理跨域的方法:
处理方法一
——在后台进行处理:通过在同域名下web服务器创建一个代理
例如某个前端页面想要调用上海的服务器,但它们不是同源的,但是它和北京的服务器是同源的,那就可以通过让北京服务器作为一个代理,先让北京的服务器从上海的服务器获取资源,再返回给前端就可以了。
处理方法二
——JSONP
JSONP可以解决主流浏览器跨域数据访问的问题
【注意】JSONP只能处理GET请求的跨域
例如:
在www.aaa.com的页面中写了如下代码:
<script>
function jsonp(json) {
alert(json['name']);
}
</script>
<script src = "http://www.bbb.com/jsonp.js"></script>
其中有个script标签写的是bbb.com页面的地址,意思就是bbb.com这个页面是可以跨域用到aaa.com页面的js对象的
然后在bbb.com的页面中就可以使用aaa.com的js对象了,如下:
jsonp('name':'张三','age':21);//张三
下面以我做的一个前后端数据交互的案例来做这个的例子:https://blog.youkuaiyun.com/Sunday97/article/details/91883933
看了上面这篇文章下面的案例才会容易理解点。直接在上面的前后端数据交互的这个案例来做改造
前端的代码修改的话只需要将dataType的值改为jsonp,再加上一个jsonp属性,值为callback(callback名字可以自己取,只需和后台相对应)(注意dataType不要写成了datatype),这样改了以后,callback就会作为参数名和其他参数一样放在地址栏的后面传递给后台,其值会随机给生成。然后后台进行获取。
例如下面的就是在调试台看到的,可以看到请求的地址中把callback作为参数提交并给其赋了很长一串值
然后再看后端返回的信息中也会带上callback的值:
下面是修改后的前端代码
<script>
$(document).ready(function() {
//信息查询
$('#search').click(function() {
$.ajax({
type:'GET',
url:'http://127.0.0.1:80/AJax_test/data.php?number='+$('#keyword').val(),
dataType:'jsonp',//改的部分
jsonp:'callback',//改的部分
success:function(data) {
if(data.success) {
$('#searchResult').html(data.msg)
}else {
$('#searchResult').html("出现错误!" + data.msg)
}
},
error:function(jqXHR) {
alert("发生错误:" + jqXHR.statusText + jqXHR.status)
}
})
});
//信息创建
$('#save').click(function() {
$.ajax({
type:'POST',
url:'data.php',
datatype:'json',
data:{
name:$('#personName').val(),
number:$('#personNumber').val(),
job:$('#personJob').val()
},
success:function(data) {
if(data.success) {
$('#createResult').html(data.msg)
}else {
$('#createResult').html('出现错误' + data.msg)
}
},
error:function(jqXHR) {
alert('发生错误' + jqXHR.status)
}
})
})
})
同时后台也是需要修改代码的:
后端是需要获取到jsonp传递过来的callback的,然后再在要返回给前端的信息上进行修改,下面要返回给前端的是$result,所有就需要在值得前面再拼接一个 $_GET[“callback”],再将后面拼接得信息用()括起来。代码如下,只修改了GET的部分,POST部分用不到。
function search() {
//获取到callback
$jsonp = $_GET["callback"];
//检查是否有个人编号的参数
//isset检查变量是否设置;empty判断值是否为空
//超全局变量$_GET和$_POST用于收集表单数据
if(!isset($_GET["number"]) || empty($_GET["number"])) {
/*意思是如果收到的number参数没有给值即客户端没有输入number时就会执行下面的*/
echo '{"success":false,"msg":"您未输入个人编号哦!"}';
return;
}
//函数之外声明的变量拥有global作用域,只能在函数以外进行访问
//global关键词用于访问函数内的全局变量
global $person;
//获取number参数
$number = $_GET["number"];
//改为jsonp后这里也需要改变,因为是要返回给前端的
$result = $jsonp.'({"success":false,"msg":"找不到这个人哦"})';
//遍历$person多维数组,如果输入了编号number那就会在数组里面找到这个人,找不到就输出上面默认的$result
forEach($person as $value) {
if($value["number"] == $number) {
$result = $jsonp.'({"success":true,"msg":"这个人存在;编号为'.$value["number"].';姓名为'.$value["name"].';工作为'.$value["job"].'"})';
break;
}
}
echo $result;
}
处理方法三
——XHR2
HTML5提供的XMLRequest Level2已经实现了跨域以及其它的一些新功能
但是IE10以下的版本都不支持
这个方法就是在服务器端做一些小小的改造:
在后端数据页面的头部加上下面的两行代码
header("Access-Control-Allow-Origin:*");//后面的*表示所有的域都可以访问,也可以设置特定的域
header("Access-Control-Allow-Methods:POST,GET")//允许GET和POST请求都可以跨域
在用php写的后端的头部加上这两行: