zoukankan      html  css  js  c++  java
  • 前端跨域新方案尝试

    简书原文

    自从前后端开发实现了越来越彻底的分离,开发中遇到的跨域问题也随之越来越多;
    而无论是跨域请求JSONPCORS或者window跨域window.namewindow.postMessage,在实际开发使用中的表现都不够完美。
    相对来说 CORS 是官方的功能比较完善的方案,但除了需要服务器和浏览器双方同时支持外,还有很多限制,比如Access-Control-Allow-Origin:*不能发送cookie等,而且如果服务器设置不当也存在着一些安全隐患。

    当然,我写这篇的重点不是吐槽,而且解决问题的。
    更多关于跨域的资料请自行查阅,相关内容

    《浏览器的同源策略》
    《跨域资源共享 CORS 详解》
    《 深入理解前端跨域方法和原理》

    设计

    我并不是一个前端开发,在之前的很长时间里我都在做着后端开发的工作; 一个偶然的机会接触到了angularJS的前端路由,当时我就想到了一个点子——做一个`index.html`页面,这个页面只有一段js脚本,脚本的功能是将另外一个存放于静态存储服务器的html页面**整个拉过来,写到当前页面中**。

    举个栗子

    比如我有一个服务器是这样的:
    api服务站点:www.xxx.com
    静态存储服务:static.xxx.com
    登录页面:static.xxx.com/20170420/login.html (中间的数字表示版本,下面会讲到)
    登录接口:www.xxx.com/api/user/login

    index.html

    很显然,在登录页面调用登录接口是一个跨域的行为;
    所以我现在在www.xxx.com中放一个index.html页面
    内容如下:

    <script src="//static.xxx.com/config.js"></script>
    <script>
        (function (url) {
            if (/[?&]supportreload/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,内容如下:

    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/i.test(location.search)) {
        window.loadPage = arguments.callee;
    }
    

    当访问 “www.xxx.com/index.html?supportreload”的时候,会注册一个全局方法window.loadPage,可以load本地调试页面,如:

    window.loadPage("localhost:8080/login.html");
    

    页面跳转

    目前页面跳转有2个方案:

    1. 前端处理

    前端使用angularjs的路由方式,使用hash切换页面,首页永远不变;
    这种方式对前端有一定要求,后端代码不需要任何修改;

    1. 后端处理

    后端使用url重写功能,将一个固定路径的所有子路径全部映射到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"


  • 相关阅读:
    English,The Da Vinci Code, Chapter 23
    python,meatobject
    English,The Da Vinci Code, Chapter 22
    English,The Da Vinci Code, Chapter 21
    English,The Da Vinci Code, Chapter 20
    English,The Da Vinci Code, Chapter 19
    python,xml,ELement Tree
    English,The Da Vinci Code, Chapter 18
    English,The Da Vinci Code, Chapter 17
    English,The Da Vinci Code, Chapter 16
  • 原文地址:https://www.cnblogs.com/blqw/p/6751621.html
Copyright © 2011-2022 走看看