在web有一种现象:不同的域名之间相互分享资源(信息)并进行通信。
这种现象叫做:跨域。
表面上看起来多个站点之间的来往增加是非常好的,但是其中弊端却是更大的。因为你不知道其他站点会拿你分享给他的信息做什么事情。所以出于安全性的考虑,在web中跨域这种现象默认是不允许的。
如果在两个或多个站点提前说好,我可以把我们站点客户端的数据分享给你,这样就会被浏览器默认阻止,因为他们是不同域的数据,所以我们就需要通过技术手段来实现了。 能够实现跨域的手段很多,总结下来要有8个之多(可能有更多只是我不知道而已),但是今天我们只介绍其中最为常见的一种:jsonP。
本章知识点:
· 同源策略
· 天生就能跨域的标签
· jsonP的基本实现
· jsonP请求百度的数据
· jsonP的优缺点
同源策略
同源策略是浏览器出于安全性考虑指定的一套策略,目的是阻止不同域之间的信息通信。
那么什么是同源策略?
即协议(http),域名(www.xxx.com),端口(80)一致。
// 目标域名 www.xxx.com htttp://www.xxx.com (同源) htttp://www.xxx.com/index.html (同源) htttps://www.xxx.com/index.html (不同源,协议不同) htttp://xxx.com/index.html (不同源,域名不同) htttp://www.xxx.com:8080/index.html (不同源,端口不同)
如果在不同源的情况下去请求别人站点的数据,只会得到一个报错。
天生就能跨域的标签
其实在最简单的HTML标签中就有一些标签天生就能跨域的。
1,<img> 2,<iframe> 3,<link> 4,<script>
没错,这些标签都是可以引入外部资源的,他们统一的特点就是拥有src/href属性,其实是这些属性在跨域,而不是标签本身在跨域,看到这里可能你也想到了一些CSS的样式属性,比如background-image属性和border-image属性(关于这种CSS属性网上还能找到一些利用跨域它们的跨域能力实现CSS攻击的文章),也就是说凡是可以引入外部资源的属性或者标签都是可以实现跨域的。
我们在www.aaa.com中如果想要请求www.bbb.com中的数据,正常情况下ajax请求都是失败的,但是www.aaa.com中却可以加载www.bbb.com中的JS文件,这样,我们的跨域请求就能得以实现了。
jsonP的基本实现
关于jsonP的具体实现非常简单,首先我们需要两个<script>标签。
客户端代码:
// 第一个<script> <script> function getData( data ){ // 定义一个获取数据的函数 console.log( data ); } </script> // 第二个<script> // 想bbb网站发送数据请求,并且在?号后传值callback <script src="http://www.bbb.com/index.php?callback=getData"></script>
服务器端代码:
<?php $callback = $_GET['callback']; echo "$callback({data:'哈哈,跨域成功!'})"; ?>
jsonP请求百度的数据
知道了这些,我们可以玩一个模拟百度搜索的小案例试试水。
想要在外部调用百度的搜索功能我们需要知道百度放出来的接口是怎么用的。
具体如下:
https://www.baidu.com/su?wd=关键字&cb=回调函数名。
<script src="https://www.baidu.com/su?wd=jsonP&cb=getData"></script>
html代码:
<input type="text" id="txt" list="datalist"> <datalist id="datalist"></datalist>
JS代码:
// 当数据返回时的回调函数 function getData(data){ var datalist = document.getElementById('datalist'); console.log(data); for( var i=0;i<data.s.length;i++ ){ var option = document.createElement('option'); option.value = data.s[i]; option.innerText = data.s[i]; datalist.appendChild(option); } } // 当键盘每一次被按下的时候都会新建一个<script>标签插入body中 document.getElementById('txt').onkeydown = function() { var script = document.createElement('script'); script.src = 'http://www.baidu.com/su?wd='+document.getElementById('txt').value+'&cb=getData'; document.body.appendChild(script); };
好了,代码已经贴出来了,去尝试把。
jsonP的优缺点
优点
显而易见的简单方便,也不会有类似于浏览器兼容不了的毛病,直接响应数据,快速实现双向通信。
缺点
1, jsonP是从其他域中加载代码执行,这时我们对外域的安全需要有一定的认识,如果它们不安全导致的问题可能会很严重,所以这时我们除了放弃jsonP没有其他办法。
2,它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
下一篇:Unity着色器特效之遮挡渲染
Electron-HTML+CSS+JS构建跨平台桌面应用程序
27671人学习