【发布时间】:2010-10-12 15:08:40
【问题描述】:
我想在 JavaScript 中使用 JSTL 的 fmt 标记来本地化我的警报消息。
我的 JavaScript 文件是一个独立文件,当我在 js 中包含 fmt 标记时,文件浏览器会给出 JavaScript 错误。是否可以使用 web.xml 配置将.js 文件视为.jsp 文件?
谁能建议我该怎么做?
【问题讨论】:
标签: javascript jsp jstl web.xml
我想在 JavaScript 中使用 JSTL 的 fmt 标记来本地化我的警报消息。
我的 JavaScript 文件是一个独立文件,当我在 js 中包含 fmt 标记时,文件浏览器会给出 JavaScript 错误。是否可以使用 web.xml 配置将.js 文件视为.jsp 文件?
谁能建议我该怎么做?
【问题讨论】:
标签: javascript jsp jstl web.xml
是否可以使用 web.xml 配置将 .js 文件视为 .jsp 文件?
是的:
<servlet>
<servlet-name>scriptjsp</servlet-name>
<jsp-file>/script.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>scriptjsp</servlet-name>
<url-pattern>/script.js</url-pattern>
</servlet-mapping>
但是,这样做并没有实际优势,因为 JavaScript 文件的 URL 不必以“.js”结尾。决定一个文件是否为 JavaScript 文件的是它所提供的 MIME 媒体类型。您可以从 JSP 使用:
<%@ page contentType="text/javascript" %>
在顶部。然后你可以直接链接到:
<script type="text/javascript" src="/script.jsp"></script>
(除此之外:在当前的浏览器中,即使没有正确设置 Content-Type,与
我想在javascript中使用JSTL的fmt标签
这可能不是一个好主意。 fmt 标记处理字符的 HTML 转义,但您想要的是 JavaScript 字符串文字转义,例如反斜杠转义引号字符。 JSTL 不提供此功能。您的 JavaScript 字符串中会出现意外转义的“&”字符,并且在消息中使用撇号或双引号会破坏整个脚本。
此外,从 JSP 提供常用包含的脚本可能会导致性能和缓存不佳。
我建议在 JavaScript 中使用独立的语言查找系统。例如,包含每个语言的外部脚本:
<script type="text/javascript" src="/script/lang/en.js"></script>
(更改“en”以匹配您想要的任何语言),并在该文件中定义如下查找:
var msg= {
messageName: 'Message in English',
...
};
然后为脚本中的每个可本地化字符串查找msg.messageName。
【讨论】:
<script src="/script/lang/lang_<c:out value="${langCode}"/>.js"> ?
getParameter 输出被注入到 JavaScript 中而没有引用或转义。 <%= 没有显式转义是 XSS 安全漏洞;永远不要那样做。如果您想将字符串放入 JavaScript 变量中,您可以使用库来执行 JavaScript 字符串文字转义,但通常将其注入 HTML 更简单(通过使用例如 <body data-lang-code="<c:out value="$(langCode}"/>"> 进行隐式 HTML 转义,然后读取 var langCode = document.body.getAttribute('data-lang-code'); .
如果您的 javascript 与您的 JSP 页面的其余部分“内联”,则只需使用 Kees de Kooter 建议的技术。
如果您的 javascript 需要放在外部文件中(例如,用于跨页面共享),那么只需将其放在自己的 JSP 文件中即可。
<%@page contentType="text/javascript" %>
<fmt:message key="some.message" var="someMessage"/>"
<fmt:message key="another.message" var="anotherMessage"/>"
var someMessage = "${someMessage}"
var anotherMessage = "${anotherMessage}"/>"
并像这样包含它...
<script src="yourScript.jsp" language="JavaScript" type="text/javascript"></script>
然后,您可以从包含 JSP 的文件中或从包含在“yourScript.jsp”之后的任何 javascript 文件中引用“someMessage”和“anotherMessage”。
注意 contentType 属性的使用 - 'text/javascript' 防止 JSP 解析器抱怨输出不是格式正确的 XML - 并且标记引用 JSP 文件。
将这种技术与@Magner 建议的技术相结合,应该会为您带来一个明智的解决方案。
编辑:将示例更改为使用 'text/plain' 的 'text/javascript' insetad - 感谢@bobince 让我意识到这个错误(即使 'text/plain' 有效,使用 'text /javascript')。此外,如果需要国际化的字符串数量很少,并且/或者您可以证明将“资源”放在多个地方是合理的——一个用于服务器端的东西,另一个用于客户端的东西——@bobince 的技术使用动态包含是一个不错的选择。
【讨论】:
我建议您编写一个 servlet,它生成一个数组或 javascript 对象,其中包含您想要的所有本地化信息。您可以使用客户端和服务器端都可以共享的Java资源包,那么您不必混合JSP代码和Javascript代码,并且servlet响应将被浏览器缓存。
创建一个 servlet,将其映射到一个路径,让它从请求参数中读取语言环境,然后生成 Javascript 代码。
使用像<script src="/mydict?lang=en"></script> 这样的行
然后加载你的脚本<script src="/myscript.js"></script>
【讨论】:
您应该努力将您的 javascript 代码保存在与 jsp 代码不同的文件中。这是为了获得浏览器缓存、更容易维护、跨页面重用以及允许压缩。
我建议您在 jsp 中为文本创建一个全局对象,供您的 javascript 文件使用。像这样:
<script>
var text = text || {}; // play well with other jsps on the page
text.this_page_name = {
required_field_error: "<fmt:message key="required.field.error"/>",
system_error: "<fmt:message key="system.error"/>"
};
</script>
稍后你在你的 javascript 中使用它:
alert(text.this_page_name.required_field_error);
【讨论】:
您可以执行以下操作。您将翻译后的消息存储在一个变量中,以后可以在 JSP 中解析该变量。
<fmt:message key="your.alert" var="theAlert"/>
<script type="text/javascript">
alert("${theAlert}");
</script>
【讨论】:
您不能在 JavaScript 中使用标签,但有一个解决方法:将标签放入隐藏的 DIV (<div style="display: none;" id="msg"><fmt:...>
现在你可以使用JS通过ID查找DIV,得到innerHTML。
也就是说,fmt 只是 Java 的 i18n 函数的包装器,您可以在 <% %> 之间直接使用它。
【讨论】:
如果您只想接收警报消息 只需在您的 javascript 中使用此标记
假设您的 Javascript 中有以下内容:
alert("Confirm Deletion");
这可以通过在你的javascript中添加bean:message标签来国际化
alert('<bean:message key="msg.confirm"/>');
并在属性文件中添加key 值
msg.delete=Confirm Deletion
【讨论】: