《应用拆分与平台搭建最佳实践》- 跨应用平台资源

来源:互联网 发布:大屏数据可视化 编辑:程序博客网 时间:2024/05/16 15:23

《应用拆分与平台搭建最佳实践》- 跨应用平台静态资源


什么是跨应用平台静态资源

静态资源可以横跨多个应用正常使用

为什么需要做成静态资源

1.任何使用的此资源的平台风格保证一致性。
2.不需要后段做太多渲染处理,降低接入平台成本。

效果图





怎么做


可以看出,top头部,和左侧的导航,基本样式保持一致。其中,top颜色不同,是提供给每个应用个喜欢定制需要的配置颜色的方式。导航没有改颜色,当然也是可以改的。

我们如何做成这个效果呢?

两套方案:

方案一  将静态资源打包成war包,需要的应用依赖来使用,缺点很明显,应用需要往页面注入值,需要对接一系列接口,复杂。
方案二  引入一段js,所有的事情都是js去完成。业务方不关心其他细节。


两种方案笔者都有做过,笔者这里只讲第二种方案,因为更加合理。


首先,我们引入一个空的js文件

<#-- 公用静态资源 --><script type="text/javascript"        src="http://login.xiaotian.shi/js/plat/plat.js"        id="plat-resources"        env="${env}"        nav="true"        userinfo="true"></script>

使用的应用始终只调用线上的js文件,然后注入env,决定当前环境,找对应jsonp接口拿数据。(现在说复杂了点,慢慢来。)


我们引入了这段js,如下给出源码

// 此文件最好修改成纯js,在jquery之前体验更好,笔者js功底不行,不敢献丑$(function (){    // 获取当前环境    var env = $("#plat-resources").attr("env");    // 是否需要导航    var needNav =  $("#plat-resources").attr("nav");    // 是否显示个人信息    var needUserInfo = $("#plat-resources").attr("userinfo");    // 获取静态服务地址    var logginServerUrl = getSpileUrl(env);    // 最前面插入标签    // 加载公共资源页面    //    var publicDoc =        "<style>" +            "*{padding:0;margin:0;font-family:'微软雅黑';}" +            "body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,th,td,p,pre,form,input,textarea,fieldset,blockquote{padding: 0;margin: 0;}" +            ".body-top {width: 100%;height: 100px;color: white;background: black;}" +            ".body-top-left {height: 100%;width: 270px; float: left;}" +            ".body-top-left-top {height: 70px;width: 270px;font-size: 50px;padding-left: 10px;line-height: 70px;}" +            ".body-top-left-bottom {height: 30px;width: 270px;font-size: 15px;line-height: 30px;text-align: right;}" +            ".body-top-mid {float: left;}" +            ".body-top-right {float: right;margin-right: 40px; width: 400px;margin-top: 10px;}" +            ".body-top-right-count {text-align: right;margin: 5px;font-size: 20px;}" +            ".hidden {display: none}" +            "div{cursor:default}" +        "</style>" +        "<div class='body-top'>" +            "<div class='body-top-left'>" +                "<div class='body-top-left-top'>xiaotian.shi</div>" +                "<div class='body-top-left-bottom'>欢迎来到石啸天的个人网站</div>" +            "</div>" +            "<div class='body-top-mid'></div>" +                "<div class='body-top-right'>" +                    "<div class='body-top-right-count'></div>" +                    "<div class='body-top-right-user hidden'>登陆</div>" +                    "<div class='body-top-right-userinfo hidden'>" +                    "<div class='body-top-right-userinfo-username'></div>" +                    "<div class='body-top-right-userinfo-logout'>退出</div>" +                "</div>" +            "</div>" +        "</div>" +        "<style>" +            ".body-nav {top: 100px;left: 0px;width: 200px;bottom:0; height:100%;position: absolute;color: white;background: #2e68aa;padding-top: 20px;}" +            ".body-nav-item {height: 20px;font-size: 20px;padding-left: 40px;padding-top: 10px;padding-bottom: 10px;}" +            ".body-nav-item:hover{background: #1e508a}" +            ".current {background:#5387c3}" +        "</style>" +        "<div class='body-nav hidden'>" +        "</div>"        ;    $("body").prepend(publicDoc);    // 请求top头右边个人信息,和左边导航信息,进行渲染    $.ajax({        type : "get",        async:false,        url : logginServerUrl + "/cloudInfo",        dataType : "jsonp",//数据类型为jsonp        jsonp: "callback",//服务端用于接收callback调用的function名的参数        success : function(data){            var indexAccessCount = data.data.indexAccessCount;            $(".body-top-right-count").html("访问量:" + indexAccessCount);            if(data.code === 200 && "true" === needUserInfo) {                $(".body-top-right-userinfo-username").html(data.data.username + " |");                $(".body-top-right-userinfo").removeClass("hidden");                $(".body-top-right-user").addClass("hidden");                $(".body-top-right-user").click(function() {                    location.href = loginHost;                });            }            if(data.code === 200 && "true" === needNav) {                var navlist = data.data.nav;                if(navlist.length > 0) {                    var navStr = "";                    for(var i = 0 ; i < navlist.length ; i++) {                        var url =navlist[i].url;                        var nowUrl = window.location.href;                        var current = "";                        if(nowUrl.indexOf(url) > -1) {                            current = "current";                        }                        navStr = navStr + "<div class='body-nav-item "+ current +"' url='" + url + "'>" + navlist[i].name + "</div>";                    }                    $(".body-nav").html(navStr);                    $(".body-nav").removeClass("hidden");                    $(".body-nav-item").click(function(){                        var url = $(this).attr("url");                        location=url;                    })                }            }            mRealy(data);        },        error:function(){            alert('fail');        }    });    $(".body-top-right-userinfo-logout").click(function() {        $.ajax({            type : "get",            async:false,            url : logginServerUrl + "/logout",            dataType : "jsonp",//数据类型为jsonp            jsonp: "callback",//服务端用于接收callback调用的function名的参数            success : function(data){                location.href = "/";            },            error:function(){                alert('fail');            }        });    });    // 绑定高度    $(".body-nav").height(document.documentElement.clientHeight);});// 默认http// 如何组装,需要根据自己应用的域名来决定function getSpileUrl(env) {    var p = "http";    var s = ":8081";    if(typeof(env) == "undefined" || env === "product") {        env="";        // 暂时没有https环境        // p = "https";        s = "";    }    return p + "://login.xiaotian" + env + ".shi" + s;}


js文件有点长,但是不复杂

1.获取了标签的一些配置
2.写了一些html样式
3.根据环境参数,组装了接口数据请求地址
4.读取了jsonp 个人会话的数据

其中html笔者有尝试写在另一个静态文件中,然后跨域调取。但是面临几个问题:
1.延迟高
2.跨域方式不友好

这些内容不长,所以写成字符串的形式,一次渲染进去,高效快捷。


其中,绿色的login系统右上角的样式,有特殊定制,可以通过复写的方式,将样式修改掉。

例如top头部的颜色修改

.body-top {    width: 100%;    height: 100px;    /*border-bottom: 4px white solid;*/    color: white;    background: black;}

或者使用plat.js渲染完成后的回掉函数进行设置。

function mRealy(publicData) {};

其中publicData是异步请求的个人信息数据,结构可以自行设定。

这样基本完成了资源静态化的工作,但是这里有一些小细节。

比如如何提速,plat最好使用cdn加速节点,并且,jquery也需要cdn加速。版本需要手动控制,不可以经常更新。
例如plat.js?v1.0.0

这样可以提升用户体验,不过最好的方式是使用纯原生的js方式去实现,笔者js功底不好,为了赶稿子就不献丑了。

这里可以跨域访问的前提是,您完成了应用跨域访问的配置,详情请看笔者单点登录相关的帖子,里面有详细描述,跨子域名会话共享的实现。

或者您可以下载系列源码,run demo来体验



项目地址  https://github.com/shixiaotian/xiaotian.shi-plat.git
demo http://www.miledao.top/
账户密码
admin admin
user1 user1
user2 user2
user3 user3