从Web2.0开始,Ajax的诞生解决了传统表单提交页面跳转、闪白屏的问题。可以实现网页的局部更新,不仅减少了网络带宽,而且大大提高了用户体验。但Ajax并不是万能钥匙,它足以打开Web通信之门。当请求遇到跨域通信时,Ajax将无计可施。Web的快速发展使得开发更加工程化,同时需要分工维度(前后端分工细节),以扩展和维护日益复杂和庞大的项目需求.前后端分离的开发方式就是在这种需求背景下衍生出来的产物。(不想再看到之前混杂的代码了)前后端分离的开发方式,如何进行数据通信是开发者绕不过去的问题。作为同学开发的朋友的客户端浏览器,有点调皮,对同源策略有限制。当我们的数据请求遇到不同来源(跨域)时,我们不得不尝试其他通信方式。阿贾克斯不可能一路走到黑。什么是同源策略及其限制同源策略限制从一个源加载的文档或脚本如何与另一个源的资源交互。这是隔离潜在恶意文件的关键安全机制。同源要求协议、域名、端口(默认80)都相同,否则为非同源。同源策略限制:Cookies、LocalStorage、IndexDB无法读取Dom无法获取ajax请求无法发送前后端如何通信Ajax(只支持同源)WebSocket(不受同源限制)CORS(都支持,新的W3C通信标准)如何创建AjaxXMLHttpRequest对象工作流兼容性处理事件触发条件事件触发序列varxhr=XMLHttpRequest?newXMLHttpRequest():newwindow.ActiveXObject('Microsoft')vardata=opt.data,url=opt.url,type=opt.type.toUpperCase(),dataArr=[];for(varkindata){dataArr.push(k+'='+data[k]);}if(type==='GET'){url=url+'?'+dataArr.join('&');xhr.open(type,url.replace(/\?$/g,'',true);xhr.send();}if(type==='POST'){xhr.open(type,url,true);xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');xhr.send(data.join('&'));}xhr.onload=function(){if(xhr.status===200||xhr.status===304){varres;if(opt.success&&opt.successinstanceofFunction){res=xhr.responseText;if(typeofres==='string'){res=JSON.parse(资源);opt.success.call(xhr,res)}}else{if(opt.error&&opt.errorinstanceofFunction){opt.error.call(xhr,res);}}}}同源下,我们可以直接使用Ajax与后端同学通信,但是遇到跨域请求的时候,我们不得不换手上的Ajax密钥,重新分配密钥来解锁。跨域通信的几种方式JSONPHashpostMessage(HTML5)WebSocketCORS(W3C通信新标准)1.JSONPJSONP原理:客户端通过动态创建脚本标签实现异步加载,服务端回调返回客户端定义的方法名,允许客户端调用获取数据只支持Get请求(GET和POST的区别这里不详述)//客户端发送请求2.HashHash原理:通过window.onhashchange事件监听获取url中的hash值,实现数据传输。和Get一样,有Url长度限制//CodeinAvarB=document.getElementdByTagName('iframe');B.src=B.src+'#'+'data';//B中的代码window.onhashchange=function(){vardata=window.location.hash;}3.postMessagepostMessage是HTML5的API,请参考开发文档window.postMessage//A.com发送信息给B.comBwindow.postMessage('data','http://B.com')//Listenwindow.addEventListener('message',function(event){console.log(event.origin);//http://A.comconsole.log(event.source);//Bwindowconsole.log(event.data);//data},false)Application项目中的场景:页面与其打开的新窗口之间的数据传递页面与嵌套iframe消息之间的消息传递针对以上三个问题的跨域数据传递4.WebSocketWebSocket是一种在单TCP连接上进行全双工通信的协议HTML5开始提供,不受同源限制。//WebSocket代码示例varws=newWebSocket('wss://echo.websocket.org');ws.onopen=function(evt){console.log('连接打开...');ws.send('HelloWebSocket!');};ws.onmessage=function(evt){console.log('ReceivedMessage:'+evt.data);ws.close();}ws.onclose=function(evt){console.log('Connectionclosed.');}5.CORSCORS是一个W3C标准,全称是“Cross-originresourcesharing”。它允许浏览器向跨域服务器发送XMLHttpRequest请求,从而克服AJAX只能在同源上使用的限制。浏览器兼容性需要XHR(IE8/9)和XHR2(>=IE10)下的兼容性处理。//CORS代码示例fetch('/url',{method:'get',}).then(function(res){...}).catch(function(err){//error})--End--JSONP兼容性较好,可以兼容低版本浏览器,但基于Get传输数据,由于浏览器Url长度限制,数据大小会受到限制。在不考虑低版本浏览器的情况下,CORS无疑是最好的前后端通信方案(单向)。WebSocket是双向选择。多个页面之间的数据通信,比如内嵌iFrame,推荐使用postMessage。每种方案都有不同的应用场景,解决问题的方案不只有一种。在实际项目开发中,需要根据实际需要选择最优方案。参考资料html5postMessage解决跨域跨窗口消息传递干货|阮一峰,前端常用通信技术——跨域资源共享CORS详解CORS正确使用姿势转载请注明出处。
