浏览器同源策略与跨域请求
一、相关概念:
浏览器的同源策略,它是由Netscape提出的一个著名的安全策略。限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。
二、跨域请求资源的几种方式:(下面以豆瓣的公共接口为例)
1.方案一:可以把请求发到自己的服务端,再通过后台代码发起请求,再将数据返回前端。
原理:因为<script><img><iframe> 等标签不受同源策略限制,可以从不同域加载并执行资源。
function showData (result) {
var data = JSON.stringify(result); //json对象转成字符串
console.log(data)
}
$(function(){
var ele="<script src='http://api.douban.com/v2/movie/top250?count=1&start=10&callback=showData'><\/script>"
//向头部输入一个脚本,该脚本发起一个跨域请求
$("head").append(ele);
})
showData即是回调函数名称,传到后台,用于包裹数据。数据返回到前端后,就是showData(result)的形式,因为是script脚本,所以自动调用showData函数,而result就是showData的参数。
跨域数据算是请求回来了,但是比较麻烦,需要自己写脚本发起请求,然后写个回调函数处理数据,不是很方便。
2.方案二:jsonp (JSON with Padding)
原理:
- JSONP(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料, 是一种非官方的跨域数据交互协议
- JSONP 本质上是利用
<script><img><iframe>等标签不受同源策略限制,可以从不同域加载并执行资源的特性,来实现数据跨域传输。 - JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。
- JSONP 的理念就是,与服务端约定好一个回调函数名,服务端接收到请求后,将返回一段 Javascript,在这段 Javascript 代码中调用了约定好的回调函数,并且将数据作为参数进行传递。当网页接收到这段 Javascript 代码后,就会执行这个回调函数,这时数据已经成功传输到客户端了。
$(document).ready(function () {
var urld="http://api.douban.com/v2/movie/top250";
$.ajax({
url: urld,
type: "GET",
data:{
start:0,
count:1
},
dataType: "jsonp", //指定服务器返回的数据类型
// jsonp: "theFunction", //指定参数名称 指定callback这个名称后,后台也需要跟着更改。
jsonpCallback: "showData", //指定回调函数名称
success: function (data) {
var result = JSON.stringify(data); //json对象转成字符串
console.log(result)
}
});
});
缺点:jQuery ajax方式以jsonp类型发起跨域请求,其原理跟<script>脚本请求一样,只是ajax的jsonp对其做了封装,因此使用jsonp时也只能使用GET方式发起跨域请求。就算指定成POST方式,会自动转为GET方式;而后端如果设置成POST方式了,那就请求不了了。跨域请求需要服务端配合,设置callback,才能完成跨域请求。
优点:JSONP 不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行。
3.方案三:CORS ( Cross-Origin Resource Sharing)
原理:
跨源资源共享 CORS ( Cross-Origin Resource Sharing) 是一个新的 W3C 标准,它新增的一组HTTP首部字段,允许服务端其声明哪些源站有权限访问哪些资源。从而克服 Ajax 只能同源使用的限制。
简析HTTP 首部字段:
Access-Control-Allow-Origin: <origin> | *
该字段表示服务器允许哪些域可以访问该资源,其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。
Access-Control-Allow-Methods: <method>[, <method>]*
该首部字段用于预检请求的响应,指明实际请求所允许使用的HTTP方法。
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
该首部字段用于预检请求的响应。指明了实际请求中允许携带的首部字段。
CORS 与 JSONP 的比较
- JSONP 只能实现 GET 请求,而 CORS 支持所有类型的 HTTP 请求
- 使用 CORS ,开发者可以是使用普通的 XMLHttpRequest 发起请求和获取数据,比起 JSONP 有更好的错误处理
- 虽然绝大多数现代的浏览器都已经支持 CORS,但是 CORS 的兼容性比不上 JSONP,一些比较老的浏览器只支持 JSONP
浙公网安备 33010602011771号