63

How can I read/access a JSP variable from JavaScript?

Adriano
  • 19,463
  • 19
  • 103
  • 140
Siddiqui
  • 7,662
  • 17
  • 81
  • 129

6 Answers6

84
alert("${variable}");

or

alert("<%=var%>");

or full example

<html> 
<head>
<script language="javascript"> 

function access(){ 
  <% String str="Hello World"; %>
   var s="<%=str%>"; 
   alert(s); 
} 

</script> 
</head> 

<body onload="access()"> 
</body> 

</html>

Note: sanitize the input before rendering it, it may open whole lot of XSS possibilities

jmj
  • 237,923
  • 42
  • 401
  • 438
  • 3
    Also read this article, it expalins the concept of JS and JSP very clearly - http://balusc.blogspot.in/2009/05/javajspjsf-and-javascript.html – Alex Punnen May 22 '14 at 03:56
  • 1
    @JigarJoshi: I mean no offense but I think your answer is really dirty/old-school, I suspect there is simply a lot of ignorance in this topic. What do you think about my answer below? – Adriano May 23 '14 at 08:31
  • @Adr +1 to your answer i am just showing how to access it on js – jmj May 23 '14 at 16:25
  • What will happen if your string contains double quotes (") character? i think it will break the functionality it may give you the partial data – Naga Srinu Kapusetti Dec 15 '14 at 06:09
  • Yes in that case you would have to escape HTML, using `` – jmj Dec 15 '14 at 06:12
  • 2
    BAD EXAMPLE, precisely because what @NagaSrinuKapusetti mentioned. If you use this for any user input, you're entering a world of trouble. – minexew Sep 29 '16 at 11:55
  • @minexew definitely it is bad example, correcting it – jmj Sep 29 '16 at 16:37
  • this is not working if we put js code in separate file. why ? – Derrick Jul 31 '17 at 14:53
  • because separate js file doesn't get treated as templated view (i.e. JSP) – jmj Jul 31 '17 at 15:23
26

The cleanest way, as far as I know:

  1. add your JSP variable to an HTML element's data-* attribute
  2. then read this value via Javascript when required

My opinion regarding the current solutions on this SO page: reading "directly" JSP values using java scriplet inside actual javascript code is probably the most disgusting thing you could do. Makes me wanna puke. haha. Seriously, try to not do it.

The HTML part without JSP:

<body data-customvalueone="1st Interpreted Jsp Value" data-customvaluetwo="another Interpreted Jsp Value">
    Here is your regular page main content
</body>

The HTML part when using JSP:

<body data-customvalueone="${beanName.attrName}" data-customvaluetwo="${beanName.scndAttrName}">
    Here is your regular page main content
</body>

The javascript part (using jQuery for simplicity):

<script type="text/JavaScript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js"></script>
<script type="text/javascript">
    jQuery(function(){
        var valuePassedFromJSP = $("body").attr("data-customvalueone");
        var anotherValuePassedFromJSP = $("body").attr("data-customvaluetwo");

        alert(valuePassedFromJSP + " and " + anotherValuePassedFromJSP + " are the values passed from your JSP page");
});
</script>

And here is the jsFiddle to see this in action http://jsfiddle.net/6wEYw/2/

Resources:

Community
  • 1
  • 1
Adriano
  • 19,463
  • 19
  • 103
  • 140
  • This method works well with the Model object being a basic String, however if it is a JSON value, all double-quotes within the JSON would need to be escaped which is problematic. – Jamie Burke Apr 01 '15 at 10:38
  • @JamieBurke fair enough, I never tried to use it to store JSON values. There may be a generic solution to that specific problem, this would need investigating. – Adriano Apr 02 '15 at 08:53
  • I am having a hard time understanding why a 1-line solution makes you 'wanna puke', while this convoluted mess somehow doesn't. Care to enlighten me? Is there some edge case i am not considering? – katzenhut Nov 20 '15 at 13:04
  • 2
    It's a good practice: separation of concerns. It allows things like moving your javascript code (& you should) in a dedicated file. This file is usually automatically minified by your CDN or else. It's simply much more generic & scalable. Another advantage can be that when working in a team, the back-end guy can tell to the front-end guy "hey I dropped those dynamic values in data attributes x & y, it's ready to go". Oh, and you can't debug inline javascript. – Adriano Nov 20 '15 at 15:38
  • Ironically enough, this has the same problem of not escaping special characters inside the string. – minexew Sep 29 '16 at 11:56
12

Assuming you are talking about JavaScript in an HTML document.

You can't do this directly since, as far as the JSP is concerned, it is outputting text, and as far as the page is concerned, it is just getting an HTML document.

You have to generate JavaScript code to instantiate the variable, taking care to escape any characters with special meaning in JS. If you just dump the data (as proposed by some other answers) you will find it falling over when the data contains new lines, quote characters and so on.

The simplest way to do this is to use a JSON library (there are a bunch listed at the bottom of http://json.org/ ) and then have the JSP output:

<script type="text/javascript">
    var myObject = <%= the string output by the JSON library %>;
</script>

This will give you an object that you can access like:

myObject.someProperty

in the JS.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    can you provide a jsFiddle please? I very roughly get the idea. – Adriano May 23 '14 at 08:33
  • No. JSFiddle will not execute JSP. – Quentin May 23 '14 at 08:34
  • 1
    fair enough, but could you simply hardcode the value that the JSP would output? – Adriano May 23 '14 at 08:35
  • 2
    `{ "someProperty" : "some \"value\"\nwith a new line" }` – Quentin May 23 '14 at 08:37
  • 1
    +1 for the JSON approach, my solution (see my answer on this page) to use HTML5 `data-*` attributes will never scale as good as a JSON approach. Using java scriptlet inside javascript still makes me shivers but it has the advantage of preventing the back end dev to write a dedicated web service. Would you have some nice compromise in mind by any chance? – Adriano May 23 '14 at 09:34
6
   <% String s="Hi"; %>
   var v ="<%=s%>"; 
0
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script 
src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"> 

    <title>JSP Page</title>
    <script>
       $(document).ready(function(){
          <% String name = "phuongmychi.github.io" ;%> // jsp vari
         var name = "<%=name %>" // call var to js
         $("#id").html(name); //output to html

       });
    </script>
</head>
<body>
    <h1 id='id'>!</h1>
</body>

phuongmychi
  • 1
  • 1
  • 1
0

I know this is an older post, but I have a cleaner solution that I think will solve the XSS issues and keep it simple:

<script>
   let myJSVariable = <%= "`" + myJavaVariable.replace("`", "\\`") + "`" %>;
</script>

This makes use of the JS template string's escape functionality and prevents the string from being executed by escaping any backticks contained within the value in Java.

You could easily abstract this out to a utility method for re-use:

public static String escapeStringToJS(String value) {
   if (value == null) return "``";
   return "`" + value.replace("`", "\\`") + "`";
} 

and then in the JSP JS block:

<script>
   let myJSVariable = <%= Util.escapeStringToJS(myJavaVariable) %>;
</script>

The result:

<script>
   let myJSVariable = `~\`!@#$%^&*()-_=+'"|]{[?/>.,<:;`;
</script>

Note: This doesn't take separation of concerns into consideration, but if you're just looking for a simple and quick solution, this may work.

Also, if you can think of any risks to this approach, please let me know.

Colin
  • 1
  • 2
  • Isn't converting the Java object to JSON much simpler and cleaner? In what cases would you have to escape backticks? In a string perhaps? As for XSS this data is coming from a variable on your server side so if you have malicious data on your server side that's already a problem and it should be sanitized before the server accepts it. – CausingUnderflowsEverywhere Jul 28 '21 at 18:24
  • What if the value you're after isn't an object and is just a string? Also, the escaping of backticks was to remove the only way (that I can think of) that a string value could break the JavaScript template literal and execute something contained within it. For example, `"lorem\`; alert(\`hello"`. If you don't escape the backticks, it will be injected as is and when the browser loads the resulting html file, it will be executed. By escaping the backticks, you just end up with a JS string. As for the data coming from the server, you should still consider/protect against it on the front-end. – Colin Aug 02 '21 at 03:59