解决跨域的两种方案JSONP和CORS
讲跨域之前,我们先来讲同源策略(SOP),同源策略是网景公司提出的一个著名安全策略。所谓同源就是域名、协议、端口相同。例如http://www.12306.cn中,http就是超文本传输协议,12306就是域名,cn就是端口。如果两个资源需要通信,那么他必须满足SOP。而在前端中我们使用ajax进行数据请求。 一、JSONP(JSON with Padding)带填充的JSON,是一种可以在JS中绕过同源策略,并发起跨域HTTP请求的使用模式,可以启动JS的跨域HTTP请求 1、工作原理我们先来看一个例子:使用ajax请求一个普通的JSON文件。假设你使用ajax请求'http://jsonpjs.com/info.json',它会返回一个JSON文档,其中包含一些信息 { 'title': 'jsonp explaintation','author': 'Cornelius' } 浏览器接受到这个json文件后,就会把他当成字符串进行处理,但是这个字符串我们需要把它转换为对象,才能够被javascript所使用,这里我们就可以使用json.parse函数来完成。当然由于同源策略的限制,ajax只能够在同一个域中才能够使用。但是正如我们前面提到的,script是html脚本元素它可以规避SOP的检查所以我们为了请求到json文件,我们可以使用这种方式 <script src='http://jsonpjs.com/info.json'></script> 通过script元素请求资源,当文件加载完成时,浏览器会把json响应当作Javascript解析。但是这样的情况下我们还是无法获得json数据。 var jsonResponse = { 'title': 'jsonp explaintation','author': 'Cornelius' } 当文件加载完成后,我们就可以通过全局变量jsonResponse访问这个JSON对象了。当该变量包含所请求数据时,我们可以使用script.onload来通知代码。那么另外一种通过一个回调函数代替全局变量的方式来传递JSON对象 jsonHandler({ 'title': 'jsonp explaintation','author': 'Cornelius' }) 使用这种方式的好处在于,我们不需要依靠script元素的onload事件来判断json是否可用,当info.js被解析时,回调便会自动执行。这需要加载<script>元素之前,在全局环境下定义好这个回调函数 window.jsonpCallback = function (json) { // 处理这个json数据 } var script = document.createElement('script') script.src = 'http://jsonjs.com//info.js?callback=jsonpCallback' document.body.appendChild(script) 2、局限性和安全性这种跨域技术非常的简单和强大,但是他也有一些局限性和安全性 二、CORSCORS是通过一系列特殊的HTTP头来解决这一问题,这些http头信息可以允许双方判断请求成功或者失败 function makeCORSRequest(url,method) { if (typeof XMLHttpRequest === 'undefined') { return null } var xhr = new XMLHttpRequest() if ('withCredentials' in xhr) { xhr.open(method,url,true) // 标准浏览器支持cors } else if (typeof XDomainRequest !== 'undefined') { xhr = new XDomainRequest() // 支持cors的IE浏览器 xhr.open(method,url) } else { xhr = null // 不支持CORS的浏览器 } } 默认情况下,使用CORS发送请求时,浏览器不会发送任何识别信息,如cookie或者http认证头,为了发送认证信息,必须将XMLHttpRequest对象的withCredentials属性设置为true Origin---请求的源 Access-Control-Request-Method---Http请求方法 Access-Control-Request-Headers----以逗号分隔的请求自定义头 然后服务器返回的请求头 Access-Control-Allow-Origin----允许的请求源 Access-Control-Allow-Methods-----以逗号分隔的允许方法列表 Access-Control-Allow-Headers------以逗号分隔的允许头信息 Access-Control-Max-Age----预检请求的缓存时间 Access-Control-Allow-Crendentials------指名所请求的资源是否支持认证信息 当客户端收到服务器返回的信息后,就会使用前面申明的http方法进行请求
第一次写技术文章,不足的地方还请各位多多指教 [third-party javascript ---- Ben Vinegar Anton Kovalyov][2] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |