How to escape JavaScript in JSP?
Asked Answered
R

2

7

I'm totally stuck on this, I'm trying to escape a single quote in a JSP. I have some data that I'm outputting directly into a JS string and the single quotes seem to be causing issues.

Here is my code:

<dsp:droplet name="/atg/dynamo/droplet/ForEach">
  <dsp:param value="${CommerceItems}" name="array" />
  <dsp:param name="elementName" value="CommerceItem" />
  <dsp:oparam name="outputStart">
    var itemNameList ='
  </dsp:oparam>
  <dsp:oparam name="output">
    <dsp:getvalueof id="Desc" param="CommerceItem.auxiliaryData.productRef.displayName">
      ${fn:replace(Desc, "'", "\\/'")}
    </dsp:getvalueof>
  </dsp:oparam>
  <dsp:oparam name="outputEnd">';</dsp:oparam>
</dsp:droplet>

And here is the output that Im getting:

var itemNameList ='
Weyland Estate Santa Barbara Pinot Noir
Raymond \/'Prodigal\/' North Coast Cabernet Sauvignon
Chateau Haute Tuque'; 

But this is wrong, and I just need /'Prodigal'/ or no single quotes at all!


EDIT: Or I actually need to escape quotes with \ backward slash?

Ruthful answered 14/3, 2012 at 18:49 Comment(1)
Looks like its \\' stackoverflow.com/questions/1470768/…Argybargy
C
21

The forward slash is not an escape character. That's the backslash.

${fn:replace(Desc, "'", "\\'")}

(yes, it's been presented twice, because that's also an escape character in Java!)

However, you don't only need to repace ' by \', you also need to replace \n (newlines) by \\n. The string is been printed over multiple lines, which makes it also an invalid JS string variable. Your final result must basically look like this:

var itemNameList = ''
    + '\nWeyland Estate Santa Barbara Pinot Noir'
    + '\nRaymond \'Prodigal\' North Coast Cabernet Sauvignon'
    + '\nChateau Haute Tuque'; 

(please note that the syntax highlighter agrees on me here but not on yours)

There are however much more possible special characters which needs to be escaped. They are all covered by Apache Commons Lang StringEscapeUtils#escapeEcmaScript(). Much easier is to create a custom EL function which calls exactly that method. If not done yet, download and drop commons-lang.jar in /WEB-INF/lib. Then create a /WEB-INF/functions.tld file like follows:

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

    <display-name>Custom Functions</display-name>    
    <tlib-version>1.0</tlib-version>
    <uri>http://example.com/functions</uri>

    <function>
        <name>escapeJS</name>
        <function-class>org.apache.commons.lang3.StringEscapeUtils</function-class>
        <function-signature>java.lang.String escapeEcmaScript(java.lang.String)</function-signature>
    </function>
</taglib>

So that you can use it as follows:

<%@taglib prefix="util" uri="http://example.com/functions" %>
...
${util:escapeJS(Desc)}
Catabolism answered 14/3, 2012 at 19:50 Comment(3)
Spring has a ready made tag for that: s:escapeBody , so if you are using Spring, you can use it without defining own custom tags.Elwina
OmniFaces also has one: of:escapeJSCatabolism
s:escapeBody needs to be separate answer @DavidBalažicRuyter
T
0

Following up on a previous comment (How to escape JavaScript in JSP?): If you're using Spring MVC, you can use the escapeBody tag in your JSP:

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

...

<s:escapeBody>${text}</s:escapeBody>
Tin answered 8/5, 2023 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.