题目1: 什么是同源策略
两个url的协议域名和端口号都相同的情况下为同源
同源策略指的是浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。
题目2: 什么是跨域?跨域有几种实现形式
跨域就是访问非同源的URL
跨域的实现形式
1.JSONP
优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都 可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
缺点:只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
2.CORS
优点:方便。通过AJAX和设置Request Header头中Access-Control-Allow-Origin为指定可获取数据的域名即可实现跨域
3.降域
缺点:URL最后的xxx.com必须相同才能实现降域,不能在服务器间交换数据只能在两个窗口之间交换数据
4.PostMessage
缺点:不能在服务器间交换数据只能在两个窗口之间交换数据
题目3: JSONP 的原理是什么
JSONP主要是通过script的src属性不受同源约束,来请求数据。具体实现过程
1.创建一个function来处理得到的数据
2.创建一个script标签,把要跨域的网址,访问的接口以及callback=function赋值给src
var script=document.createElement('script');
script.src='http://a.swh.com:8080/getNews?callback=doSomething';
document.head.appendChild('script');
document.head.removeChild('script');//防止添加过多的script
3.后端把传递过来的函数加上括号和数据返回
4.前端得到函数和数据的拼装体并执行
题目4: CORS是什么
CORS全称跨域源资源共享,它定义了 在必须访问跨域资源时,浏览器和服务器应该如何沟通。CORS的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应应该是成功还是应该失败 。
CORS跨域只要在后端添加一个Header即可实现跨域
CORS的简单请求和复杂请求区别
简单请求的method必须是HEAD,POST,GET三者中的一个;
HTTP头包含
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type,但仅能是下列之一
application/x-www-form-urlencoded
multipart/form-data
text/plain
任何一个不满足上述要求的请求,即被认为是复杂请求。
简单请求的发送从代码上来看和普通的XHR没太大区别,但是HTTP头当中要求总是包含一个域(Origin)的信息。该域包含协议名、地址以及一个可选的端口。不过这一项实际上由浏览器代为发送,并不是开发者代码可以触及到的。另外,简单请求必须包含Access-Control-Allow-Origin
复杂请求表面上看起来和简单请求使用上差不多,但实际上浏览器发送了不止一个请求。其中最先发送的是一种"预请求",此时作为服务端,也需要返回"预回应"作为响应。预请求实际上是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行。
参考文章
res.header(Access-Control-Allow-Origin,'http://a.jrg.com:8080')//只允许http://a.jrg.com:8080访问
res.header(Access-Control-Allow-Origin,'*')//允许所有网站访问
题目5: 根据视频里的讲解演示三种以上跨域的解决方式
CORS
<img src="/uploads/default/original/2X/9/9a0625949d73919f7ea2605cef4698ea528201e7.png" width="690" height="376">
JSONP
<img src="/uploads/default/original/2X/7/7a11684af4c8424035f4fac61e9ec1974cb27a9e.png" width="690" height="376">
前端代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>news</title>
<style>
.container{
width: 900px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<ul class="news">
<li>第11日前瞻:中国冲击4金 博尔特再战</li>
<li>男双力争会师决赛 </li>
<li>女排将死磕巴西!</li>
</ul>
<button class="change">换一组</button>
</div>
<script>
$('.change').addEventListener('click', function(){
var script=document.createElement('script');
script.src='http://a.swh.com:8080/getNews?callback=render';
document.head.appendChild(script);
})
function render(data){
var html='';
for(var i=0;i<data.length;i++){
html+='<li>'+data[i]+'</li>';
}
$('.news').innerHTML=html;
}
function $(id){
return document.querySelector(id);
}
</script>
</html>
后代代码:
app.get('/getNews',function(req,res){
var news = [
"第11日前瞻:中国冲击4金 博尔特再战200米羽球",
"正直播柴飚/洪炜出战 男双力争会师决赛",
"女排将死磕巴西!郎平安排男陪练模仿对方核心",
"没有中国选手和巨星的110米栏 我们还看吗?",
"中英上演奥运金牌大战",
"博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
"最“出柜”奥运?同性之爱闪耀里约",
"下跪拜谢与洪荒之力一样 都是真情流露"
]
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;
if(cb){
res.send(cb + '('+ JSON.stringify(data) + ')');
}else{
res.send(data);
}
})
降域
<img src="/uploads/default/original/2X/e/e35a7acdc23eb0e9ea4564c07ef82ae0ecca508d.jpg" width="690" height="376">