跨域:指的是浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。例如abc.com下面的js不能调用def.com中的js、对象或数据(因为abc.com和def.com是不同域),所以跨域就出现了。
同源策略:指的是域名相同、协议相同、端口相同,例如我在本地localhost需要请求网络服务器上资源,这时候浏览器就会报错(No 'Access-Control-Allow-Origin' header is present on the requested)。
这个就是同源策略的保护,如果浏览器对JavaScript没有同源策略的保护,那么一些重要的机密网站将会很危险。
http://www.abc.com/index.html 调用 http://www.abc.com/server.php(非跨域) http://www.abc.com/index.html 调用 http://www.edf.com/server.php(主域名不同:abc/edf,跨域) http://abc.abc.com/index.html 调用 http://def.abc.com/server.php(子域名不同:abc/def,跨域) http://www.abc.com:80/index.html 调用 http://www.abc.com:81/server.php(端口不同:80/81,跨域) http://www.abc.com/index.html 调用 https://www.abc.com/server.php (协议不同:http/https,跨域)
注:localhost和127.0.0.1虽然都指向本机,但也属于跨域的哦。
解决办法:
一、JSONP格式数据
JSONP全称是 JSON with Padding,是为了解决跨域请求资源而产生的解决方案,是一种依靠开发人员创造出的一种非官方跨域数据交互协议。也是比较常见的一种跨域方式,其背后原理就是利用了script标签不受同源策略的限制,在页面中动态插入了script,script标签的src属性就是后端api接口的地址,并且以get的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,并且将数据以参数的形式传递回去。
1、基于Script标签实现跨域
前端设置:<script src="http://www.abc.com/server.php?callback=show"></script>
后端设置:
empty($_GET)?$callback='demo':$callback=$_GET['callback']; $pdo = new PDO("mysql:host=localhost;dbname=h5_10",'root',''); $pdo->query('set names utf8'); $result = $pdo->query("select * from goodsinfo limit 5"); $data = $result->fetchAll(PDO::FETCH_ASSOC); echo $callback."(".json_encode($data).")";
2、基于jQuery实现跨域
jQuery已经把跨域封装到ajax上了,而且封装得非常的好,使用起来也特别方便,是一般的ajax请求:
注:JSONP只支持GET请求,不支持POST请求。
二、使用反向代理服务器
可以参考博主的另外一篇文章(使用Nginx服务器解决前后端分离开发时的跨域问题),这样做的目的就是相当于前端页面(www.abc.com/index.html)需要调用后端接口(www.edf.com/server.php),可以写一个接口服务(www.abc.com/server.php),由这个服务接口在后端去调用(www.edf.com/server.php)并拿到返回值,然后再返回给index.html,这就是一个代理的模式,相当于绕过了浏览器端,自然就不存在跨域问题。
三、设置服务端的header头文件
1、header("Access-Control-Allow-Origin:http://localhost");
-- 指定只有http://localhost可以访问
xhr.open('get','http://localhost/8-1.php'); //此时可以请求数据
xhr.open('get','http://127.0.0.1/8-1.php'); //此时不可以请求数据
2、header("Access-Control-Allow-Origin:*");
-- 都可以访问
总结
当然还有其他实现跨域的方式比如在ie8、9下XDR跨域方案,flash方案,以上是一些常用的跨域方案,都各有利弊,比如:jsonp只能发送get请求、服务器跨域需要另起服务器等等,大家可以根据自己项目需求选择适合的解决方案,如果对于跨域还有其他看法或者文中出现错误,欢迎大家留言)。
博主只是一名前端的小白,只是把自己用到的知识分享一下,要是有什么不对的地方,欢迎大家提出~~
2017年9月22日 下午1:35 1F
写的还可以