【发布时间】:2015-11-27 22:40:40
【问题描述】:
我有几个 WebSockets 端点,例如,
wss://localhost:8181/ContextPath/Push
所有此类端点 URL 都硬编码在单独的外部 JavaScript 文件 (.js) 中。这些 JavaScript 文件在需要时包含在相应的 XHTML 文件中。主机名和上下文路径应以编程方式进行评估,而不是在需要它们的地方进行硬编码。
主机名 (localhost:8181) 可以在 JavaScript 中使用 document.location.host 获取,但在 JavaScript 中没有标准/规范的方式来获取应用程序运行的上下文路径。
我正在做类似以下的事情。
在主模板上声明一个全局 JavaScript 变量,如下所示。
<f:view locale="#{bean.locale}" encoding="UTF-8" contentType="text/html">
<f:loadBundle basename="messages.ResourceBundle" var="messages"/>
<ui:param name="contextPath" value="#{request.contextPath}"/>
<ui:insert name="metaData"></ui:insert>
<h:head>
<script type="text/javascript">var contextPath = "#{contextPath}";</script>
</h:head>
<h:body id="body">
</h:body>
</f:view>
</html>
其中主机名和上下文路径被硬编码的 JavaScript 文件包含在相应的模板客户端或模板的北、南、东和西的任何部分中,如下所示。
<html lang="#{bean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:form>
<h:outputScript library="default" name="js/websockets.js" target="head"/>
</h:form>
仅出于观点考虑,websockets.js 如下所示(您可以直接忽略它)。
if (window.WebSocket) {
// The global variable "contextPath" is unavailable here
// because it is declared afterwards in the generated HTML.
var ws = new WebSocket("wss://"+document.location.host + contextPath + "/Push");
ws.onmessage = function (event) {
// This handler is invoked, when a message is received through a WebSockets channel.
};
$(window).on('beforeunload', function () {
ws.close();
});
} else {}
现在,在主模板中声明的全局 JavaScript 变量 contextPath 预计将在包含的 JavaScript 文件中可用,即 websockets.js。然而这是不真实的。
发生的情况是包含的 JavaScript 文件,即 websockets.js,其中试图访问全局变量 contextPath,被放置在生成的 HTML 中硬编码的 <script> 标记之前之前 <head> 主模板中的标签。
换句话说,全局 JavaScript 变量 contextPath 实际上在被声明之前尝试在包含文件 websockets.js 中使用。
无论如何,如何摆脱在外部 JavaScript 文件中硬编码上下文路径?
这样做的唯一目的是与 CSS 文件不同,EL 不在外部 JavaScript 文件中进行评估。因此,#{} 的东西除非放在 XHTML 文件中,否则不会起作用。
【问题讨论】:
标签: javascript jsf el