题目1: 什么是同源策略
同源策略是指浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。
本域是指:
- 协议相同
- 域名相同
- 端口相同
同源策略的目的是为了保证用户信息的安全,防止恶意的网站窃取数据。
题目2: 什么是跨域?跨域有几种实现形式
只要协议、域名、端口有任何一个不同,都被当作是不同的域,不同的域的网站之间发出资源请求时就叫跨域。
跨域的方式:
- JSONP:JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。JSONP也叫填充式JSON,是应用JSON的一种新方法,只不过是被包含在函数调用中的JSON,例如:
callback({"name","trigkit4"});
JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。
JSONP使用例子:
<script>
function dosomething(jsondata){
//处理获得的json数据
}
</script>
<script src="http://localhost:8080/get?callback=dosomething"></script>
js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。
router.get('/jsonp', function(req, res) {
var name = req.query.callback;//得到回调函数名
var data = ['a','b','c'];//要返回的数据
res.send(name + '(' + JSON.stringify(data) + ')');//输出
})
最终,输出结果为:dosomething(['a','b','c']);
- CORS:CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
例如:
router.get('/cors', function(req, res) {
var note = ['你好']
res.header("Access-Control-Allow-Origin", "http://localhost:8080") //设置Access-Control-Allow-Origin
res.send(note)
})
- 降域:通过修改document.domain来跨子域
- postMessage: window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
题目3: JSONP 的原理是什么
script标签的src属性不受同源策略限制,可以跨域引用资源,JSONP由两部分组成:回调函数和数据。要想成功的引用数据需要服务器配合:将数据包裹在对应回调函数中一同返回。使用方法参考上一题。
题目4: CORS是什么
CORS是跨域资源共享(Cross-Origin Resource Sharing),定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-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
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。
简单请求:对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段如:Access-Control-Request-Method。
复杂请求:非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。