在了解实现跨域请求之前,我们需要了解一下问题:
- 什么是跨域
- 如何区分是否跨域
- 是谁造成的跨域,为什么要跨域
- 如何解决跨域
- 跨域请求的原理
下面我们一个个问题的分析:
什么是跨域?
不同的域名之间进行数据的访问,会造成跨越问题,导致的结果是取不到请求的数据。
如何区分是否跨越?
看请求地址和被请求的地址是否是同源的。所谓 "同源" 是指:
- 协议名称相同
- 域名相同
- 端口号相同
当请求数据时,不是同源请求,那么就属于跨域
是谁造成的跨域,为什么要跨域?
是浏览器造成的跨域,其实我们发送请求时,数据已经到了浏览器中,只是浏览器没有把数据给我们。
那浏览器为什么不将数据给出呢?
是为了保证用户信息的安全,防止恶意的网站窃取数据。 (默认情况下,不允许外界的网站向本网站注入数据),这就是为什么要有跨域。
如何解决跨域?
- jsonp是解决跨域的一种方案
- 利用php做桥接实现跨域(其实这个过程没有经过浏览器)
- 跨域资源共享(Cross Origin Resource Sharing, CORS)是一个解决跨域问题的好方法,从而可以使用XHR
从不同的源加载数据和资源
jsonp跨域请求的原理?
在 html dom中,script标签是可以跨域访问服务器上的数据的,因此,可以指定script 的src 属性为跨域的 url,从而实现跨域访问。
- 在本地定义一个方法:
function fn(param){ console.log(param); }
- 定义script标签,在发送请求时,将函数名称传递给服务器
<script src='myFile.php?callback = fn'> </script>
- 在服务器中接收传递的参数
$fn = $_GET['callback'];
- 在服务器端输出要执行的内容,此处输出,相当于执行函数命令,相当于 fn(1)
echo $fn.'(1)'
这里面有一个浏览器解析机制,如果服务器返回的是js代码,会立马执行改内容。
在angualrJS中的 jsonp 实现跨域
$http({
url:'jsonpFlile.php',
method:'jsonp',
params:{
callback:'JSON_CALLBACK',
}
}).success(function (res) {
console.log(res);
})
这中方式在1.6一下可以实现,但是1.64版本中使用方式不尽相同:
$http.jsonp('jsonpFlile.php',{
jsonpCallbackParam: 'jsonCallback'
}).then(
function (res) {
console.log(res.data);
})
在 jQuery中的 jsonp 跨域
var url = "http://www.mydomain.com/api/jsonpFile.php?symbol=IBM&callback=?";
jQuery.getJSON(url, function(data){
alert("Symbol:" + data.symbol + ", Price:" + data.price);
});
在jsonpFile.php文件中
$jsondata = "{symbol:'IBM', price:120}";
echo $_GET['callback'].'('.$jsondata.')';
jsonp的优点是:它不像XMLHttpRequest
对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
jsonp的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript
调用的问题
利用php做桥接来实现跨域
在index.php中:
$url = 'https://api.douban..com/v2/book/12204';
echo file_get_content($url);
在index.html中,正常的发送ajax请求
$http({
url:'index.php',
method:'get',
}).success(function (res) {
console.log(res);
}).error(function (e) {
console.log(e);
})
CORS--跨域资源共享(Cross Origin Resource Sharing, CORS)
CORS规范简单地扩展了标准的XHR对象,以允许JavaScript发送跨域的XHR请。 它会通过预检查(preflight)来确认是否有权限向目标服务器发送请求。
预检查可以让服务器接受或拒绝来自全部服务器、 特定服务器或一组服务器的请求。 所以,客户端和服务端应用需要协调工作,才能向客户端或服务器发送数据。
这里主要看一下在angularJS中使用CORS,
设置:为了在AngularJS中使用CORS,首先要告诉AngularJS我们正在使用CORS。
myApp.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
这样就可以发送CORS请求了。
CORS完成跨域,也需要服务器端的支持 :
支持CORS的服务器必须在响应中加入几个访问控制相关的头。
- Access-Controll-Allow-Origin
这个头的值可以是与请求头的值相呼应的值,也可以是 * ,从而运行接收从任何来源发来的请求。
- Access-Control-Allow-Credentials