如何在 JSP 上转义撇号或引号(由 JavaScript 使用)

Posted

技术标签:

【中文标题】如何在 JSP 上转义撇号或引号(由 JavaScript 使用)【英文标题】:How to escape apostrophe or quotes on a JSP (used by JavaScript) 【发布时间】:2010-12-01 01:02:05 【问题描述】:

我有一个用户表单。如果用户输入带有'" 的字符串作为其中的一部分,我没有问题。表单已提交并正确保存到数据库。我的问题是当我重新加载页面时(所有条目都可以修改并在显示之前加载到 JSP 中的列表中)。在加载页面时,我收到一条错误消息:

missing ) after argument list 'Caroline's message', \n

我需要做什么来转义这个字符串以便在前端显示它?

这是我在前端用来读取数据并将其存储在 javascript 对象中的代码。我不完全确定我需要逃到哪里。导致问题的字段是 c.getComName:

communications[<%=i%>][1] = new CommObject('<%=c.getComId()%>', '<%=c.getComName()%>');

已生成 HTML 更新:

communications[0][1] = new CommObject('101', 'Caroline's Message');

【问题讨论】:

搞砸了是什么意思?那些角色是怎么搞砸的? 抱歉,进一步调查显示我的问题不在于提交表单,而是提交后再次检索数据,请参阅更新后的问题 你能显示生成的 html 吗? 添加了 HTML,我删除了关于 jquery 的问题的第二部分,在查看了 HTML 之后,这是唯一有 ' 的地方,所以这是我需要转义的地方。 【参考方案1】:

我更喜欢避免在我的页面中间使用 scriptlet,并且在 JavaScript 代码中使用它们时不得不(越来越频繁地)使用它们来转义字符串。我想要一种Expression Language (EL) 转义字符串的方式。我创建了一个非常小的自定义标签库,仅用于此目的:

Utilities.java:

package com.mycom.taglibs;

import org.apache.commons.lang.StringEscapeUtils;

public class Utilities 
    public static String escapeJS(String value) 
        return StringEscapeUtils.escapeJavaScript(value);
    

mytaglib.tld:

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">

  <description>My Tag Library</description>
  <display-name>Tag Utils</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>myt</short-name>

  <function>
    <description>
        JavaScript Escape function
    </description>
    <name>escapeJS</name>
    <function-class>com.mycom.taglibs.Utilities</function-class>
    <function-signature>java.lang.String escapeJS(java.lang.String)</function-signature>
  </function>
</taglib>

并且,在 JSP 页面中:

<%@ taglib prefix="myt" uri="/WEB-INF/mytaglib.tld" %>
The escaped string is: $myt:escapeJS(variableHoldingTheString)

【讨论】:

谢谢,这是个好建议 :) 我只想补充一点,您不需要 Utilities.java 类。您可以像这样直接使用 StringEscapeUtils 构造 taglib: org.apache.commons.lang.StringEscapeUtilsjava.lang.String escapeJavaScript(java.lang.String) 用新的包和函数名称更新@machinery 的答案:&lt;function-class&gt;org.apache.commons.lang3.StringEscapeUtils&lt;/function-class&gt; &lt;function-signature&gt;java.lang.String escapeEcmaScript(java.lang.String)&lt;/function-signature&gt; 但是,我没有使用这个答案,因为我的 taglib 标签抱怨了The content of element type "taglib" must match "(tlibversion,jspversion?,shortname,uri?,info?,tag+)",我不知道如何修复它。 【参考方案2】:

使用 Apache StringEscapeUtils.escapeJavaScript 函数。

Escapes the characters in a String using JavaScript String rules.

Escapes any values it finds into their JavaScript String form.
Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)

So a tab becomes the characters '\\' and 't'.

【讨论】:

另外,如果这个字符串是一个 URL(例如 javascript:launchURL()你可以把这个 StringEscapeUtils.escapeJavaScript 和 URLEncoder.encode 结合起来生成一个 javascript-安全网址。 请注意,在 commons lang 3.x+ 中这已更改为 StringEscapeUtils.escapeEcmaScript(String) 它还将任何非拉丁字母符号转换为其 unicode 序列 ("кириллица" -> "\\u043A\\u0438\\u0440\\u0438\\u043B\\u043B\\u0438\ \u0446\\u0430")。问题只是关于单引号。 另一个注意事项,在较新版本的 commons-lang3 中,这被标记为已弃用,以支持 commons-text 中的等效类。【参考方案3】:

fn:escapeXml 在 JavaScript 中不起作用。它将' 替换为#&amp;0039; 在执行JavaScript 时仍然会导致错误。

只有以 JavaScript 方式转义才是正确的:\'

Apache StringEscapeUtils.escapeJavaScript 函数为您执行此操作。为它创建一个 taglib 大大简化了事情。

【讨论】:

【参考方案4】:

我们也有来自 Spring 的非常好的解决方案:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<spring:message code="$propertyName" javaScriptEscape="true"/>

所以,这篇文章的问题可以这样解决:

communications[&lt;%=i%&gt;][1] = new CommObject('&lt;spring:message code="$c.comId" javaScriptEscape="true"/&gt;', '&lt;spring:message code="$c.comName" javaScriptEscape="true"/&gt; &lt;%=c.getComName()%&gt;');

【讨论】:

我认为这个答案只有在 propertyName 指向 MessageResource 中的消息时才有效。要打印转义的 propertyName 的实际文本,您需要 text="$propertyName" 代替。非常方便的标签,不过!我会经常使用它。【参考方案5】:

您可以使用 JSTL 转义函数fn:escapeXml() 来摆脱由于单引号(`)引起的异常。 以下示例演示了差异。

例如:

<c:set var="string1" value="This is abc's first String."/>
<c:set var="string2" value="This is abc's second String."/>

<p>With escapeXml() Function:</p>
<p>string (1): $fn:escapeXml(string1)</p>

<p>Without escapeXml() Function:</p>
<p>string (2): $fn:escapeXml(string2)</p>

结果

string(1):这是 abc 的第一个字符串。

string(2):这是 abc 的第二个 String。

【讨论】:

【参考方案6】:

当您从 CommObject 类返回 HTML 时,在名称之前添加 \" 而不是 '(例如 Caroline 的消息)

像这样:return "\"" + comName + "\"";

【讨论】:

仍然不高兴,我错过了)在参数列表“卡罗琳的消息”之后,\n。只是为了确认我需要同时转义 ' 和 " 不,只是转义“,并省略单引号【参考方案7】:

当我将数据从我的 servlet 传递到我的 JSP 然后到我的代码 Javascript 以创建 JSON 对象时,我遇到了这个问题,所以我需要它 ' 但它呈现为 &amp;#39 ; 不能在JSON 对象中,所以要修复我只需将我的JSP 从写' 更改为` 6 键,它工作正常。

【讨论】:

【参考方案8】:

这很奇怪。

怎么样:

'<%=c.getComName().replaceAll("\\'","\\\\'")%>'

如果可行,您只需要弄清楚如何添加 \"。

【讨论】:

它实际上并没有修复它,这让我感到惊讶! :-o 我想您需要在将名称传递回前端之前对其进行预处理。 :( 永远不要编写自己的转义代码!例如,您忘记考虑原始字符串中可能存在的反斜杠字符。使用久经考验的代码,如提到的StringEscapeUtils【参考方案9】:

你可以使用 JSP 核心标签:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>      
var jsVar = "<c:out value='$stringVariable' />";

【讨论】:

Javascript 和 HTML/XML 的转义文本是有区别的。您的回答解决了后者,但这个问题要求的是前者。因为 c:out 会生成 HTML/XML 实体,这些实体在 JS 代码中并不总是有效。 您将能够打破 js 上下文:“非常容易切换到包含(但不限于)分号、等号、空格、加号等字符的执行上下文,所以谨慎使用。”来自owasp.org/index.php/… 是的,注入&lt;/script&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;script&gt;var jsVar2 = "foobar 应该会弹出警报,因为浏览器会在包含var jsVar = .. 语句的&lt;/script&gt; 上下文中监视&lt;/script&gt;,而不管字符串文字子上下文如何。我认为即使注入"; alert(1); var jsVar2 = "foobar 也可以。谢谢@Tarion

以上是关于如何在 JSP 上转义撇号或引号(由 JavaScript 使用)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 函数中使用单引号(撇号)转义 JSON 值

如何正确转义 JSP 标记中的三重嵌套引号

html页面常用转义字符

如何在 PHP 中去除特殊的引号字符?

如何插入包含撇号(单引号)的值?

反序列化包含引号和撇号的 JSON 字符串