一、 使用jsonp实现跨域
1. 跨域问题
从一个网站的页面中 ,去请求另外一个不同的网站中国的内容
由此引出了iframe标签:(利用iframe标签可以在当前页面下去访问另一个页面的内容。)
<h2>我是利用iframe标签获得另一个页面</h2>
<iframe src='http://www.baidu.com'></iframe>
① iframe标签的用法:
- 首先,使用iframe标签,将需要引入的页面对应的url写入到src属性中。
<iframe src='http://www.baidu.com'></iframe>
- 其次,在script脚本中,获取iframe元素
var iframe = document.querySelector('iframe');
- 获取到iframe元素后,可以发现该元素中有一个contentWindow属性且contentWindow下有个document。
- 获取到的document元素,是另一个页面的document文档,并且,当获取到了document就可以获取该页面的元素,进行一系列的操作
//获取iframe元素
var iframe = document.querySelector('iframe');
//iframe元素中有一个contentWindow属性
var iframeWindow = iframe.contentWindow;
//contentWindow下有一个document属性
var iframeWindowDocument = iframeWindow.document;
//获取到另一个页面的button元素
var iframeWindowDocumentBtn = iframeWindowDocument.querySelector("button");
//为iframe指定的页面的button元素添加一些样式,以作测试
iframeWindowDocumentBtn.style.backgroundColor = "red";
iframeWindowDocumentBtn.style.border = "0";
② 注意:
iframe缺点:
处于安全性考虑,两个页面必须是同源,才能再当前页面下利用 js获取另一个页面的内容,如果不同源,获取将会出错。
同源:
同源指的是:域名,协议,端口完全相同(同源策略是浏览器的一种安全策略)
③ 解决跨域问题—(jsonp)
由于使用iframe必须是同源的,才能进行处理,因此出现的跨域问题,利用jsonp来解决。
2. jsonp
① 原理:
script标签的src属性,支持跨域
② 核心:
- 发送的只能是get请求(服务端用$_GET获取数据)
- 服务端获取发送的方法:
- $_GET [‘callback’] ——-(假设获取到的内容为eatFood)
- 返回给浏览器时是:$_GET [‘callback’].’()’——拼接一个括号再返回到浏览器端
- 假设浏览器的script标签获取到的eatFood(),将会调用当前页面中的eatFood方法,并从中获取到了从服务器发来的数据
<script>
//定义eatFood函数
function eatFood(foodName) {
console.log('我被调用了哦!');
console.log(foodName);
}
</script>
<!-- 引入文件,并将参数callback=eatFood发送到服务器上 -->
<script src='http://192.168.43.207/Ajax%20And%20PHPLearning/23-jsonp/02-jsonp.php?callback=eatFood'></script>
echo $_GET['callback'].'({"西红柿":"红色","黄瓜":"绿色"})';
3. jsonp的使用步骤(方法1)
- 首先利用script标签的src属性,发送get请求,去到php页面
<script type='text/javascript' src="http://192.168.43.207/Ajax%20And%20PHPLearning/23-jsonp/jsonp.php"></script>
- 并且对服务器发送了一组参数,如:key为callback 值为eatFood
- 在php页面中,将$_GET[‘callback’]获得到的值
- 进行处理(如:加上括号——这样返回到浏览器就是调用了eatFood函数),再返回到浏览器端
- 由于返回的是eatFood(),且在html页面中定义了eatFood函数,因此就会调用该方法,得到输出结果
注意:由于使用了jsonp这种交互,其他服务器端运行这个页面时,也会有相同的输出结果,这就是跨域
4. 利用jQuery中的$_ajax()方法发送jsonp请求(方法2)
在jQuery中,已经封装好了一个方法,用作jsonp请求,来解决跨域问题。
$_ajax(),并且该方法会自动帮我拼接一个callback(默认值)
① jsonpCallback($.ajax()方法中的一个参数)
该属性为jsonp指定一个回调函数,这个值将用来取代jQuery自动生成的随机函数名,用来让jQuery生成独特的函数名
② 使用$_ajax()方法发送jsonp步骤:
- dataType属性值要为 “ jsonp ”。
- 如果要更改传到服务器上的数据,则增加jsonCallback属性,值为自己要发送的数据或方法。
//回调函数内容
function myJsonPCallBack(data) {
console.log('自己写的 回调函数名'+data);
}
//button按钮点击事件,发送jsonp请求
$('#jqJsonp').click(function () {
$.ajax({
//规定发送请求的url
url:'03.jq_jsonp.php',
//请求发送成功的回调函数
success:function(data){
console.log(data);
},
//设置数据类型为jsonp
dataType:'jsonp',
//指定回调函数
jsonpCallback:"myJsonPCallBack"
})
})
根据上述代码的做法,当触动点击事件,将会把请求发送到对应的url
且:请求发送url 如:
二、json与jsonp的区别
json和jsonp是两种概念,不要混淆
① json(一种数据交换格式)
json是某种格式的字符串。基本上所有的语言都有将json字符串转化为该语言对象的语法。
格式:
var str = '{"name":"rose",
"age":"18",
"sex":"girl",
"skill":"beautiful"
}';
//
- JSON.parse()方法—JS中将json字符串转化为js对象
使用JSON对象的parse方法使得json格式的字符串转变为对应的js对象
var jsonObj = JSON.parse(str);
- 注意:
json格式的字符串转化为对应的js对象是在:注册的事件中实现的
ajax.onreadystatechange = function() {
if(ajax.readyState == 4 && ajax.status == 200) {
//json字符串 ===> js对象
var jsonObj = JSON.parse(ajax.responseText);
//再使用js对象获取值,修改页面显示
console.log(jsonObj.name);
console.log(jsonObj.sex);
console.log(jsonObj.age);
}
}
② jsonp(一种解决跨域问题的请求方式)json with padding
jsonp是一种解决跨域问题的请求方式(和json截然不同)
本质是利用了script标签具有可跨域性的特点。
//利用script的src属性,发送jsonp请求
<script type='text/javascript' src="http://192.168.43.207/Ajax%20And%20PHPLearning/23-jsonp/jsonp.php?callback=eatfood"></script>