跨域
实际中我们经常需要到不同的域名下获得数据,由于同源策略的存在我们无法通过AJAX等方式直接获取数据 ,需要一些方法来实现跨域,主要的跨域方式有
- jsonp
- CORS (cross-origin-resource-shareing //iE10及以上支持)
- 降域 (具有局限性,只有是同属于一个域名的二级域名还能够使用这种方式)
- postMessage
下面就具体介绍下每一种跨域方式
1. JSOP
JSONP 的原理是script标签的src属性不受同源策略影响,网页通过添加一个元素,相当于向服务器发送了一个get请求,服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>example</title>
<style media="screen">
.newsFrame{
margin: 0 auto;
}
</style>
</head>
<body>
<div class="newsFrame">
<ul class="content">
<li>上学</li>
<li>消费</li>
<li>生活</li>
</ul>
<button class="btn">换一批</button>
</div>
<script type="text/javascript">
$('.btn').addEventListener('click',function(){
var script = document.createElement('script');
script.src='http://b.har.com:8080/getNews?callback=appendhtml';
document.head.appendChild(script);
document.head.removeChild(script);
})
function appendhtml(news){
var html = '';
for(var i=0; i<news.length; i++){
html += '<li>' + news[i] + '</li>'
}
console.log(html)
$('.content').innerHTML = html
}
function $(id){
return document.querySelector(id)
}
</script>
</body>
</html>
后端代码
app.get('/getNews', function(req, res) {
var news = [
"看电视",
'大学在学习',
'大家在跑步',
'天气预报',
'我要吃饭',
'看电视'
]
var data = [];
for(var i=0; i<3; i++){
var index = parseInt(Math.random()*news.length);
data.push(news[index]);
news.splice(index,1);
}
var cb = req.query.callback;
res.send( cb + '(' + JSON.stringify(data) + ')' );
});
2. CORS
CORS全称跨域资源共享(crossing-origin resourse sharing),是一种ajax跨域 请求资源的方式,支持现代浏览器,支持IE10以上。
实现的方式很简单,当你使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回的结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断响应头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以,CORS的表象是让你觉得他与同源的AJAX的请求没啥区别,代码完全一样。
后端代码
app.get('/getNews', function(req, res) {
var news = [
"看电视",
'大学在学习',
'大家在跑步',
'天气预报',
'我要吃饭',
'看电视'
]
var data = [];
for(var i=0; i<3; i++){
var index = parseInt(Math.random()*news.length);
data.push(news[index]);
news.splice(index,1);
}
res.header("Access-Control-Allow-Origin","http://a.jrg.com:8080");//CORS
//res.header("Access-Control-Allow-Origin","*");
res.send( data );
});
CORS 的请求分两种,这也是浏览器为了安全做的一些处理,不同情况下浏览器执行的操作也是不一样的,主要分为两种请求,当然这一切我们是不需要做额外处理的,浏览器会自动处理的。
1. 简单请求(simple request)
只要同时满足以下两大条件,就属于简单请求。
条件:
1 ) 请求方法是以下三种方法中的一个:
HEAD
GET
POST
2 )HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
2. 非简单请求
条件:
除了简单请求以外的CORS请求。
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是 application/json。
跨域资源共享 CORS
3. 降域
降域主要应用在域名相同的网站之间的跨域。
http://a.jrg.com:8080/a.html
http://b.jrg.com:8080/a.html
根据同源策略上面的两个网址不是本域,但他们的域名相同,都是jrg.com所以可以通过降域的方式跨域 。具体的实现方法分别在对应的网页的JS中加入
document.domain = "jrg.com";
4. postMessage
postMessage作为html5新引入的API允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。