且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

摆脱外部JavaScript文件中Web应用程序的上下文路径的硬编码

更新时间:2022-12-22 13:07:34


所包含的JavaScript文件名为 websockets.js 其中全局变量 contextPath , 之前硬编码< script> 主模板中生成的HTML < head> 标记中的标记

What happens is that the included JavaScript file named websockets.js where the global variable contextPath is attempted to be accessed, is placed before the hard-coded <script> tag in the generated HTML <head> tag in the master template

这是出乎意料的。您在< h内声明了< h:outputScript> 引用 websockets.js 文件:body> target =head。这应该在 c>< h:head> 中已经声明的所有其他脚本资源>之后结束。另见a.o. 如何在Facelets模板中引用CSS / JS /图像资源?毕竟,这似乎是由捆绑的PrimeFaces引起的 HeadRenderer 有意自动包含一些CSS资源并负责&lt ; facet name =first | middle | last>

This is unexpected. You declared the <h:outputScript> referring websockets.js file inside <h:body> with target="head". This is supposed to end up after all other script resources already declared in <h:head>. See also a.o. How to reference CSS / JS / image resource in Facelets template? After all, this appears to be caused by PrimeFaces bundled HeadRenderer which is intented to auto-include some CSS resources and take care of the <facet name="first|middle|last">.

这对PF家伙来说是值得的问题报告(如果还没有完成的话) )。同时,***的办法是通过显式注册JSF实现自己的 HeadRenderer 来关闭它,如下面的 faces-config.xml (假设您使用的是Mojarra)。

This is worth an issue report to PF guys (if not already done). In the meanwhile, your best bet is to turn off it by explicitly registering the JSF implementation's own HeadRenderer back as below in faces-config.xml (provided that you're using Mojarra).

<render-kit>
    <renderer>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.Head</renderer-type>
        <renderer-class>com.sun.faces.renderkit.html_basic.HeadRenderer</renderer-class>
    </renderer>
</render-kit>

明确包含PrimeFaces主题特定的 theme.css 如下所示< h:head>

And explicitly include the PrimeFaces theme-specific theme.css as below in <h:head>:

<h:outputStylesheet library="primefaces-aristo" name="theme.css" />






回到真正的问题,


Coming back to the real question,


无论如何,如何摆脱硬编码外部JavaScript文件中的上下文路径?

将其设置为基本URI(注意:HTML4 / IE6-8不支持相对路径)。

Either set it as base URI (note: relative path isn't supported in HTML4 / IE6-8).

<h:head>
    <base href="#{request.contextPath}/" />
    ...
</h:head>





var baseURI = $("base").attr("href");

或者将其设置为HTML根元素的数据属性。

Or set it as data attribute of HTML root element.

<!DOCTYPE html>
<html lang="en" data-baseuri="#{request.contextPath}/" ...>
    ...
</html>





var baseURI = $("html").data("baseuri");






不相关到具体问题,作为建议,透明地涵盖http + ws和https + wss,考虑使用 location.protocol 而不是硬编码 wss


Unrelated to the concrete problem, as a word of advice, to transparently cover both http+ws and https+wss, consider using location.protocol instead of a hardcoded wss.

var ws = new WebSocket(location.protocol.replace("http", "ws") + "//" + location.host + baseURI + "Push");