同源策略
简单来说,就是网站A去调用网站B的数据。(例如滴滴调用高德地图)
浏览器的同源策略,该策略会阻止ajax跨域访问
同源策略(Same origin policy)是一种约定,它是浏览器的一种安全功能。
所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。一段脚本只能读取来自于同一来源的窗口和文档的属性。
同源策略在什么情况下会起作用呢? 当web 页面使用多个<iframe>元素或者打开其他浏览器窗口的时候,这一策略就 会起作用。
解决跨域问题有三种方式(对于端口和协议的不同,只能通过后台来解决。我们要解决的是域名不同的问题。)
方式一:服务器代理实现ajax跨域
php中有一个函数 file_get_contents。 该函数能够获取到其他网站的数据。
www.study.study.com服务器的a.html文件希望能够获取到www.demo.com服务器data.php文件返回的数据,但是受限于同源策略,不能直接获取。a.html文件通过ajax请求本服务器中的prox.php文件,proxy.php文件中使用file_get_contents函数将data.php的数据获取到,再返回给a.html的ajax请求。
方式二:cors实现ajax跨域
cors: 跨域资源共享。
同源策略是浏览器的策略。但是如果服务器允许程序进行跨域访问,那么浏览器就不会对返回的数据进行限制了。
核心方法: 在服务器端(PHP文件中)声明不用进行同源限制
如果设置为*则是所有外部网站都可以获取数据
header('Access-Control-Allow-origin: *');
只允许www.study.com网站访问并获取数据
header('Access-Control-Allow-origin:http://www.study.com');
方式三:jsonp跨域
JSONP(JSON with Padding) : 是一种解决ajax跨域访问的方案。
由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON 数据。
核心思想:
浏览器虽然有同源策略,但是 src 和 href 两个属性却可以跨域访问。 可以利用这一“漏洞”发送ajax请求。
处于安全考虑,服务器不允许ajax跨域获取数据,但是可以跨域获取文件内容,所以基于这一点,可以动态创建script标签,使用标签的src属性访问js文件的形式获取js脚本,并且这个js脚本中的数据是函数调用,该函数调用的参数是服务器返回的数据,为了获取这里的参数数据,需要事先在页面中定义回调函数,在回调函数中处理服务器返回的数据,这就是解决跨域问题的主流解决方案,本质上使用的并不是ajax技术。
Jsonp并不是一种数据格式,而json是一种数据格式,jsonp是用来解决跨域获取数据的一种解决方案。
虽然 jsonp 的实现跟 ajax 没有半毛钱关系,jsonp是通过 script的src实现的,但是最终目的都是向服务器请求数据然后回调,而且为了方便,所以jquery把 jsonp 也封装在了 $.ajax 方法中,调用方式与 ajax 调用方式略有区别
优点: 它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest 或 ActiveX 的支持; 能够直接访问响应文本,支持在浏览器与服务器之间双向通信
缺点: JSONP 是从其他域中加载代码执行。如果其他域不安全,很可能会在响应中夹带一些 恶意代码,而此时除了完全放弃 JSONP 调用之外,没有办法追究。因此在使用不是你自己 运维的Web 服务时,一定得保证它安全可靠。 它只支持 GET请求而不支持 POST等其它类型的 HTTP 请求;它只支持跨域 HTTP 请 求这种情况,不能解决不同域的两个页面之间如何进行 JavaScript调用的问题
$.ajax方法跨域操作 --- jsonp方式
核心:
必须设置请求类型为get --- type: ‘get’
必须设置dataType为jsonp --- dataType: ‘jsonp’
必须额外设置一个jsonp参数,该参数值可以是任何英文字符串,常用fn和callback
示例:
$.ajax({
url: 'http://www.study.com/test/2.php',
type: 'get',
dataType: 'jsonp',
jsonp: 'fn',
success: function(msg){
alert(msg);
alert(msg.name);
}
})
案例:
www.study.com/ajax-3/jsonp/index.html跨域访问www.demo.com/test/3.php文件中的内容
① www.study.com/ajax-3/jsonp/index.htm
<script type="text/javascript"> $.ajax({ url:"http://www.demo.com/test/3.php", type: 'get', dataType:'jsonp', jsonp: 'fn', success: function(msg){ alert(msg); } }) </script>
<?php $fn = $_GET['fn']; $str = '{"id":1,"name":"zs"}'; echo $fn."(".$str.")"; ?>
注意点: jsonp设置为什么, 后台的php程序使用$_GET来接收数据时,就用什么作为下标
jsonp: ‘fn’; ---> $_GET[‘fn’];
jsonp:’aaa’ ---> $_GET[‘aaa’];
核心:
必须设置请求类型为get --- type: ‘get’
必须设置dataType为jsonp --- dataType: ‘jsonp’
必须额外设置一个jsonp参数,该参数值可以是任何英文字符串,常用fn和callback
示例:
$.ajax({
url: 'http://www.study.com/test/2.php',
type: 'get',
dataType: 'jsonp',
jsonp: 'fn',
success: function(msg){
alert(msg);
alert(msg.name);
}
})