更新时间:2019年07月26日 11时13分44秒 来源:黑马程序员论坛
前言 Web2.0以来,Ajax的出世,解决了传统表单提交页面跳转,闪烁白屏等问题。使得Web页面可以实现局部更新,不仅减少了网络带宽,还大大提升了用户体验。 但Ajax并非是一把万能的钥匙,足以打开Web通信这扇大门,当请求遇到跨域通信时,Ajax就没辙了。 (一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准) Web的快速发展让开发走向工程化的同时,要求工作维度进行划分(前端后端分工明细),以便扩展维护日益复杂庞大的项目需求。而前后端分离的开发方式正是这种需求背景下衍生的产物。(以前混编的代码现在是再也不想看到) 前后端分离的开发方式,如何进行数据通信是开发人员绕不过去的问题。作为开发同学的小伙伴客户端的浏览器,有点小调皮还做了一个同源策略的限制,当我们的数据请求遇到不同源的情况下(跨域),我们就得尝试其它的通信方法,不能Ajax一条道走到黑 同源策略及限制 同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进 行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。 同源要求协议,域名,端口(默认80)三者都相同,否则为非同源 同源策略限制: * Cookie, LocalStorage和IndexDB无法读取 * Dom无法获取 * Ajax请求不能发送 前后端如何通信 * Ajax(仅支持同源) * WebSocket (不受同源限制) * CORS (都支持,新的W3C通信标准) 如何创建Ajax * XMLHttpRequest对象的工作流程 * 兼容性处理 * 事件的触发条件 * 事件的触发顺序 代码: var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft') var data = opt.data, url = opt.url, type = opt.type.toUpperCase(), dataArr = []; for (var k in data) { 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) { var res; if (opt.success && opt.success instanceof Function) { res = xhr.responseText; if (typeof res === 'string') { res = JSON.parse(res); opt.success.call(xhr, res) } } else { if (opt.error && opt.error instanceof Function) { opt.error.call(xhr, res); } } } } 同源下,我们可以直接使用Ajax来与后端同学做数据通信,但是遇到跨域请求时,我们就得更换手中这把Ajax的钥匙,来重新配钥匙开锁 跨域通信的几种方式 * JSONP * Hash * postMessage (HTML5) * WebSocket * CORS (新的W3C通信标准) JSONP * JSONP原理:客户端通过动态创建script标签异步加载来实现,服务端callback返回客户端定义的方法名,让客户端进行调用获取数据。 只支持Get请求 (GET与POST的区别这里暂不细讲) 代码: // 客户端发送请求 Hash * Hash原理:通过window.onhashchange事件监听来获取url中hash值来实现数据传输。与Get一样,有Url长度限制 代码: // A中代码 var B = document.getElementdByTagName('iframe'); B.src = B.src + '#' + 'data'; // B中代码 window.onhashchange = function(){ var data = window.location.hash; } postMessage * postMessage是HTML5的API,可参考开发文档window.postMessage 代码: // A.com向B.com发送信息 Bwindow.postMessage('data','http://B.com') // B中监听 window.addEventListener('message', function(event){ console.log(event.origin); // http://A.com console.log(event.source); // Bwindow console.log(event.data); // data }, false) 项目中应用场景: * 页面和其打开的新窗口的数据传递 * 多窗口之间消息传递 * 页面与嵌套的iframe消息传递 * 上面三个问题的跨域数据传递 WebSocket * WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,本身不受同源限制。 代码: // WebSocket代码示例 var ws = new WebSocket('wss://echo.websocket.org'); ws.onopen = function (evt) { console.log('Connection open ...'); ws.send('Hello WebSocket!'); }; ws.onmessage = function (evt) { console.log('Received Message: ' + evt.data); ws.close(); } ws.onclose = function (evt) { console.log('Connection closed.'); } CORS * CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。 * 浏览器兼容在XHR(IE8/9)及XHR2(>=IE10)下需要做兼容处理。 代码: // CORS代码示例 fetch('/url', { method: 'get', }).then(function(res){ ... }).catch(function(err) { // 错误 }) 总结 * JSONP有更好的兼容性,能兼容低版本浏览器,但是基于Get传输数据,会因为浏览器Url长度限制而限制数据大小。CORS在不考虑低版本浏览器时,无疑是目前最好前后端通信方案(单向),双向选择WebSocket,而多个页面之间的数据通信,如内嵌iFrame等,则推荐postMessage。 * 每种方案有不同的应用场景,解决问题不只有一种解决方案,实际项目开发中,需根据实际需求来挑选最优的方案。 |
推荐了解热门学科
java培训 | Python人工智能 | Web前端培训 | PHP培训 |
区块链培训 | 影视制作培训 | C++培训 | 产品经理培训 |
UI设计培训 | 新媒体培训 | 产品经理培训 | Linux运维 |
大数据培训 | 智能机器人软件开发 |
传智播客是一家致力于培养高素质软件开发人才的科技公司,“黑马程序员”是传智播客旗下高端IT教育品牌。自“黑马程序员”成立以来,教学研发团队一直致力于打造精品课程资源,不断在产、学、研3个层面创新自己的执教理念与教学方针,并集中“黑马程序员”的优势力量,针对性地出版了计算机系列教材50多册,制作教学视频数+套,发表各类技术文章数百篇。
传智播客从未停止思考
传智播客副总裁毕向东在2019IT培训行业变革大会提到,“传智播客意识到企业的用人需求已经从初级程序员升级到中高级程序员,具备多领域、多行业项目经验的人才成为企业用人的首选。”
中级程序员和初级程序员的差别在哪里?
项目经验。毕向东表示,“中级程序员和初级程序员最大的差别在于中级程序员比初级程序员多了三四年的工作经验,从而多出了更多的项目经验。“为此,传智播客研究院引进曾在知名IT企业如阿里、IBM就职的高级技术专家,集中研发面向中高级程序员的课程,用以满足企业用人需求,尽快补全IT行业所需的人才缺口。
何为中高级程序员课程?
传智播客进行了定义。中高级程序员课程,是在当前主流的初级程序员课程的基础上,增加多领域多行业的含金量项目,从技术的广度和深度上进行拓展。“我们希望用5年的时间,打造上百个高含金量的项目,覆盖主流的32个行业。”传智播客课程研发总监于洋表示。
黑马程序员热门视频教程【点击播放】
Python入门教程完整版(懂中文就能学会) | 零起点打开Java世界的大门 |
C++| 匠心之作 从0到1入门学编程 | PHP|零基础入门开发者编程核心技术 |
Web前端入门教程_Web前端html+css+JavaScript | 软件测试入门到精通 |