简书原文css
自从先后端开发实现了愈来愈完全的分离,开发中遇到的跨域问题也随之愈来愈多;
而不管是跨域请求JSONP,CORS或者window跨域window.name
,window.postMessage
,在实际开发使用中的表现都不够完美。
相对来讲 CORS 是官方的功能比较完善的方案,但除了须要服务器和浏览器双方同时支持外,还有不少限制,好比Access-Control-Allow-Origin:*
不能发送cookie等,并且若是服务器设置不当也存在着一些安全隐患。html
固然,我写这篇的重点不是吐槽,并且解决问题的。
更多关于跨域的资料请自行查阅,相关内容前端
《浏览器的同源策略》
《跨域资源共享 CORS 详解》
《 深刻理解前端跨域方法和原理》angularjs
我并非一个前端开发,在以前的很长时间里我都在作着后端开发的工做;
一个偶然的机会接触到了angularJS的前端路由,当时我就想到了一个点子——作一个index.html
页面,这个页面只有一段js脚本,脚本的功能是将另一个存放于静态存储服务器的html页面整个拉过来,写到当前页面中。web
好比我有一个服务器是这样的:
api服务站点:www.xxx.com
静态存储服务:static.xxx.com
登陆页面:static.xxx.com/20170420/login.html (中间的数字表示版本,下面会讲到)
登陆接口:www.xxx.com/api/user/loginajax
很显然,在登陆页面调用登陆接口是一个跨域的行为;
因此我如今在www.xxx.com中放一个index.html页面
内容以下:后端
<script src="//static.xxx.com/config.js"></script> <script> (function (url) { if (/[?&]supportreload\b/i.test(location.search)) { window.loadPage = arguments.callee; } if (url) { var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); url += [(url.indexOf("?") < 0 ? "?" : "&"), "_", new Date().getTime()].join(""); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { var base = ['<base href="', url, '" />'].join(""); var html = xhr.responseText; html = html.replace(/(\<head[^>]*\>)/, "$1" + base); if (html === xhr.responseText) { html = base + html; } document.open(); document.write(html); document.close(); } else { document.write("'" + url + "' 加载失败(" + xhr.statusText + ")..."); } } } xhr.open("GET", url, true); xhr.send(null); } })(window["index.page"]); </script>
其中引入了一个//static.xxx.com/config.js
,内容以下:api
window["index.page"] = "//static.xxx.com/20170420/login.html"
流程大体是这样的
能够看到,在index.html页面被加载的同时,我引用了一个config.js,这个js也是存放在静态资源服务器的,里面声明了一个参数window["index.page"]
,而index.html页面会用这个变量中声明的url拉取页面,并write到当前页面中。跨域
能够看到导入的页面是"//static.xxx.com/20170420/login.html",中间的数字能够看作是版本,前端每次发布均可以建立一个新的文件夹,保留以前的发布内容,若是遇到问题须要回滚之类的操做,只须要将config.js
中的window["index.page"]
指向新的版本页面便可;浏览器
另外页面中的css,js等资源的问题,我在load page操做的时候会在页面中加入<base >
标签,保证大部分的相对引用资源都是没问题的(js代码中的地址不受base影响,如ajax);
为了方便本地调试,特别加了这一段
if (/[?&]supportreload\b/i.test(location.search)) { window.loadPage = arguments.callee; }
当访问 “www.xxx.com/index.html?supportreload”的时候,会注册一个全局方法window.loadPage
,能够load本地调试页面,如:
window.loadPage("localhost:8080/login.html");
目前页面跳转有2个方案:
index.html
,如:config.Routes.MapHttpRoute( name: "webhtml", routeTemplate: "web/{*pattern}", defaults: new { controller = "webhtml", action = "index" } );
前端使用相对路径的方式切换页面,config.js
部分代码作一些简单的调整;
如:
window["index.page"] = "//static.xxx.com/20170420" + location.pathname
如今就能够动态拉取页面了,好比访问
www.xxx.com/web/login.html的时候,会拉取并展现"//static.xxx.com/20170420/login.html"
www.xxx.com/web/user/manager/info.html的时候,会拉取并展现"//static.xxx.com/20170420/user/manager/info.html"