使用jsonp在html中加载jsp页面(适用于前后端分离项目的index.html入口页访问jsp加载相关资源)

如何在html中加载jsp页面

背景

在实际工作中,可能会见证公司技术栈的变迁,比如说:从写jsp到前后端分离。但在这个过渡的阶段中,可能会遇到非得在html页面中加载jsp页面的情况。下面来总结一下如何实现这种需求吧~

业务场景

当前是一个前后端分离的项目,使用的是vue-cli脚手架,使用webpack进行打包,入口页为index.html。由于历史原因,需要用到一个公共组件 xxxComponent,由于该公共组件适用于大部分用jsp写的项目,因此提供的引入方式是<%=XXXDef.getPackage("xxxComponent", "~1.1.0")%>,实际上就是生成加载公共组件资源的link标签和script标签。由于html和jsp不同,我们不能在html页面里面直接使用服务器端代码,那么我们是否可以在html中加载jsp页面,从而获取到需要的组件呢?答案当然是可以的。

解决方案

通过jsonp的方式,将目标作为js形式加载过来,尽管其实对方是一个jsp。
我们可以在项目的public文件夹下看到index.html页面,在同个文件夹下创建xxxComponent.jsp。
在index.html页面请求同路径下的xxxComponent.jsp页面的数据,这个jsp页面自执行函数里生成了需要的link、script标签。

<%-- 引入所需要的包 --%>
<%@ page import="xxx"%>
<%
        response.setHeader("Content-Type", "application/javascript; charset=UTF-8");
        
        String root = XXXDef.getXxxComponentRoot(); // 业务需要
        String version = "xxxComponent";
		
		// 业务需要
		// 1. 由于组件内部需要用到a、b、c、d,我们在window定义好这些变量,且都是从以下jar包拿到的。这也是html里做不到的!
		// 2. 创建一段脚本:自执行函数里动态生成link标签用于加载组件的css资源,script用于加载组件的js资源。
		// 3. 最后将脚本以字符串的形式输出
        String script = "(function(){" +
          "window.a='" + root + "/" + version  +"';" +
          "window.b='//" + Web.getAVal() + "/" + version + "';" +
          "window.c='" + Web.getBVal() + "';" +
          "window.d=" + Web.getCVal() + ";" +
          "var l = document.createElement('link');" +
          "l.rel='stylesheet';l.href='" + XXXDef.getXxxComponentPath("css_xxxComponent") + "';" +
          "var s = document.createElement('script');" +
          "s.src = '" + XXXDef.getXxxComponentPath("js_xxxComponent") + "';" +
          "var n = document.getElementsByTagName('script')[0];" + 
          "n.parentNode.insertBefore(l, n);" + 
          "n.parentNode.insertBefore(s, n);" + 
          "})()";

        out.print(script);
%>

在index.html页面里,引入这个jsp:

<script type="text/javascript" src="<%= BASE_URL %>xxxComponent.jsp"></script>

由于index.html页面是项目的入口页,我们可以看到访问项目时发起了一个http请求,请求了http://yourProjectDomain/xxxComponent.jsp页面,页面里输出以下内容(通过控制台找到相关请求在Response中可以看到):

(function() {
    window.a = '//commonComponents.cn/xxxComponent'; // 解释:这些都是后端拿到的具体的值
    window.b = '//commonComponents.cn/xxxComponent';
    window.c = 'projectName';
    window.d = true;
    var l = document.createElement('link');
    l.rel = 'stylesheet';
    l.href = '//commonComponents.cn/xxxComponent/css/xxxComponent.css?v=202106041200';
    var s = document.createElement('script');
    s.src = '//commonComponents.cn/xxxComponent/js/xxxComponent.js?v=202106041200';
    var n = document.getElementsByTagName('script')[0];
    n.parentNode.insertBefore(l, n);
    n.parentNode.insertBefore(s, n);
}
)()

因为是以javascript文件形式加载过来的,所以他会在index.html插入动态添加的以下几个标签(打开控制台,在Elements中head标签里可以找到组件相关的资源标签):

<link rel="stylesheet" href="//commonComponents.cn/xxxComponent/css/xxxComponent.css?v=202106041200">
<script src="//commonComponents.cn/xxxComponent/js/xxxComponent.js?v=202106041200"></script>

至此,项目成功引入需要的组件!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值