一、什么是跨域
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
简单的说就是 只要 协议、域名(主域名、子域名)、端口不同就会当成不同的域,不同域之间的数据调用就是跨域。
URL | 说明 | 是否允许通讯 |
www.test1.com/index.php | 同一域名下 | 允许 |
www.test1.com/test.php | ||
www.test1.com/service.php | 不同域名下 | 不允许 |
www.test2.com/service.php | ||
http://www.test1.com/index.php | 不同的协议下 | 不允许 |
https://www.test1.com/index.php | ||
www.test1.com:8080/service.php | 不同的端口下 | 不允许 |
www.test1.com:8081/service.php |
二、如何解决
2.1方法一:前端页面ajax跨域,可使用jsonp数据类型
说明:jsonp 只支持 get请求,不支持post
www.test2.com/index.php
<script type="text/javascript"> url = 'http://www.test3.com/index.php'; /*$.post(url,'',function(jsondata){ console.log(jsondata) });*/ function success(jsondata){ console.log(jsondata) } $.ajax({ url:url, dataType:'jsonp', data:{"jsonReturn":"success"}, # json 数据返回调用 success 方法 processData: true, type:'get', error:function(XMLHttpRequest, textStatus, errorThrown) { console.log(XMLHttpRequest.status); console.log(XMLHttpRequest.readyState); console.log(textStatus); }}); </script>
www.test3.com/index.php
<?php header('Content-Type:application/json; charset=utf-8'); $data = array( 'id'=>2 ,'content'=>'hello world' ); $info = (isset($_GET['jsonReturn']) ? $_GET['jsonReturn'] : 'callback' ) . '('. json_encode($data) .')';
# 没有传jsonRetrun 则默认返回调用callback方法,并传实参json_encode($data) exit($info);
2.2方法二:代理,通过后端获取 其他域的api 接口返回内容,再返回此数据,就不存在跨域问题了,这就是代理
举例:不如说www.test1.com/index.html 需要用到www.test2.com/service.php 的接口数据.可以写一个接口 www.test1.com/index.php 通过curl 获取 www.test2.com/service.php 返回的数据,再return 。供www.test1.com/index.html 前端调用这个接口。这样就解决了跨域问题
2.3方法三:在接口端修改header ,允许所有来源访问(这是不安全的,不推荐)
只需要在PHP接口处添加即可
header('Access-Control-Allow-Origin:*');//允许所有来源访问 header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
2.4方法四:websocket
说明:WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很棒的实现
2.5方法五:html 标签 <iframe>
说明:在主页面中嵌套其他域的页面。可以使用此标签。在主页面中是可以通过js 获取 <iframe>内的内容的。具体请自行百度。
2.6方法六: 基于token的验证方式
如果你采用的是基于token 的验证方式,而非使用session验证,你可以在nginx中配置
location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; }
设置服务器属性 Access-Control-Allow-Origin * ,让服务器能接受到来自所有域的请求
token 验证方式的优点:
1.无状态、可扩展
2.支持移动设备
3.跨程序调用
4.安全