In Specific
I need a way to print JSON representation of a string value into the html page via thymeleaf.
In detail
I'm having a model attribute which contains a string which is actually a string representation of the JSON
My thymeleaf code
<script th:inline="javascript">
var value = [[${data.scriptValue}]];
</script>
print the variable as below
var value = '[[\"asd\",\"3\"],[\"asd\",\"1\"],[\"asdasd\",\"1\"]]';
But I want something like this as a javascript/JSON array
var value = [["asd","3"],["asd","1"],["asdasd","1"]];
How to do this in thymeleaf?
Note: I know I can do this from JSON.Parse but i need a way to do this from thymeleaf :)
Update - 2015/12/24
This feature is available in Thymeleaf 3
Refer The Thymeleaf textual syntax in https://github.com/thymeleaf/thymeleaf/issues/395
// Unescaped (actual answer)
var value = [(${data.scriptValue})];
//or
var value = [# th:utext="${data.scriptValue}"/];
// Escaped
var value = [[${data.scriptValue}]];
//or
var value = [# th:text="${data.scriptValue}"/];
It's not possible at Thymeleaf 2. As Patric LC mentioned, there are two issues reported for this.
unescaped inline for scripts/css #12
Use Jackson for Javascript inlining of JSON #81
#Faraj, new version of Thymeleaf provides this functionality. They implement features for the issues that you mentioned. You can look here:
http://www.thymeleaf.org/doc/articles/thymeleaf3migration.html
The main features:
Three textual template modes: TEXT, JAVASCRIPT and CSS.
New syntax for elements in textual template modes: [# ...] ... [/].
Inlined output expressions allowed, both escaped ([[...]]) and unescaped ([(...)]).
Intelligent escaping of JavaScript (as literals) and CSS (as identifiers).
Parser-level (/*[- ... -]*/) and prototype-only (/*[+ ... +]*/) comment blocks.
Natural templates applied to JAVASCRIPT scripts and CSS style sheets by means of wrapping elements and/or output expressions inside comments (/*[# ...]*/).
Related
I'm using Thymeleaf to process html templates, I understood how to append inline strings from my controller, but now I want to append a fragment of HTML code into the page.
For example, lets stay that I have this in my Java application:
String n="<span><i class=\"icon-leaf\"></i>"+str+"</span> \n";
final WebContext ctx = new WebContext(request, response,
servletContext, request.getLocale());
ctx.setVariable("n", n);
What do I need to write in the HTML page so that it would be replaced by the value of the n variable and be processed as HTML code instead of it being encoded as text?
You can use th:utext attribute that stands for unescaped text (see documentation). Use this with caution and avoid user input in th:utext as it can cause security problems.
<div th:remove="tag" th:utext="${n}"></div>
If you want short-hand syntax you can use following:
[(${variable})]
Escaped short-hand syntax is
[[${variable}]]
but if you change inner square brackets [ with regular ( ones HTML is not escaped.
Example within tags:
<div>
[(${variable})]
</div>
In Firebug and other DevTools you can get the DOM properties and values corresponding to an HTML element.
How can such values be extracted using selenium-java code?
I had tried getAttribute(), but it seems to be working only for HTML attributes and not for DOM properties like "value" or "spellcheck" etc.
The reason I went for this approach is that the value associated with the <input> text field (snippet below) is run-time generated and data is bound to it using Knockout. And hence it's not possible to capture them with standard approaches like getText(), getAttribute("value"), getAttribute("text"), getAttribute("innerHTML"), getAttribute("innertext"), etc.
HTML snippet for the HTML element:
<input class="form-control" type="text" style="cursor: text" readonly="readonly" data-bind="textInput: url">
I know this is an old question but it might give someone else a hand out
Use this in the console
$$("input.form-control").value
if it returns the required you will have to execute the Javascript using WebDriver i.e.
driver.ExecuteScript("var data = arguments[0].value; return data;", (Element as RemoteWebElement)
According to the Selenium documentation, there is only the getAttribute() function, which is described as follows:
Get the value of a the given attribute of the element. Will return the current value, even if this has been modified after the page has been loaded. More exactly, this method will return the value of the given attribute, unless that attribute is not present, in which case the value of the property with the same name is returned (for example for the "value" property of a textarea element). If neither value is set, null is returned. ...
According to this, getAttribute("value") should return the DOM property value in case there is no HTML attribute named value.
If that's not the case, it may be a timing issue. I.e. the value is read by Selenium before it gets set.
In Selenium 4 use getDomAttribute() and getDomProperty().
So I am trying to build some HTML markup in a Spring controller. Sample code:
append(sb ,"<div class="myDiv">");
which is generating the following HTML source on browser:
<div class=""myDiv"">
append code:
private void append(StringBuilder sb, String value) {
sb.append(value).append(System.getProperty("line.separator")).append('\n');
}
My question is, Why generated HTML code has an extra set of "" around text myDiv? My controller method is that produces this HTML:
#RequestMapping(value = "/getSerialRanking", method = RequestMethod.POST, produces = MediaType.TEXT_HTML_VALUE)
#ResponseBody
public String getSerialRankings(#RequestParam(value = "serialNumber", required = false) String serial){
In html single word properties without quotes are legal so
<div class=myDiv>
is converted by your browser to this
<div class="myDiv">
Based on that knowledge I'm assuming your Spring Controller is auto converting the value to <div class=""myDiv""> Then your browser converts the " to a legal HTML entity ".
The " is ignored until it reaches the browser where it is converted to a legal HTML entity "
Finally I think your safe to remove the " for this case. Or if your using more than one words in your HTML property go with #ElliottFrisch solutions:
append(sb ,"<div class=\"myDiv\">");
append(sb ,"<div class='myDiv'>");
Don't use HTML quotes, I think you want to change
append(sb ,"<div class="myDiv">");
to escape the double quotes like
append(sb ,"<div class=\"myDiv\">");
or HTML allows you to mix quotes, so you could say
append(sb ,"<div class='myDiv'>");
I get html code from server to build freemarker.ftl.
Example:
Server return:
String htmlCode="<h1>Hello</h1>";
freemarker.ftl
${htmlCode}
except:Hello
actually: <h1>Hello</h1>
what can i do?
By default FreeMarker has no auto-escaping on, so it should print that value as HTML. But as it doesn't as you say, I can imagine two possibilities:
You are inside <#escape x as x?html>...</#escape>, or that was added to the template by a custom TemplateLoader. In that case, in 2.3.x you have to write <#noescape>${htmlCode}</#noescape>. (In 2.4 it will be much less verbose if everything goes as planned.)
That value was escaped before it reaches FreeMarker. So the template already gets <h1>Hello</h1> as the string.
The reason for this "escapes" me.
JSON escapes the forward slash, so a hash {a: "a/b/c"} is serialized as {"a":"a\/b\/c"} instead of {"a":"a/b/c"}.
Why?
JSON doesn't require you to do that, it allows you to do that. It also allows you to use "\u0061" for "A", but it's not required, like Harold L points out:
The JSON spec says you CAN escape forward slash, but you don't have to.
Harold L answered Oct 16 '09 at 21:59
Allowing \/ helps when embedding JSON in a <script> tag, which doesn't allow </ inside strings, like Seb points out:
This is because HTML does not allow a string inside a <script> tag to contain </, so in case that substring's there, you should escape every forward slash.
Seb answered Oct 16 '09 at 22:00 (#1580667)
Some of Microsoft's ASP.NET Ajax/JSON API's use this loophole to add extra information, e.g., a datetime will be sent as "\/Date(milliseconds)\/". (Yuck)
The JSON spec says you CAN escape forward slash, but you don't have to.
I asked the same question some time ago and had to answer it myself. Here's what I came up with:
It seems, my first thought [that it comes from its JavaScript
roots] was correct.
'\/' === '/' in JavaScript, and JSON is valid JavaScript. However,
why are the other ignored escapes (like \z) not allowed in JSON?
The key for this was reading
http://www.cs.tut.fi/~jkorpela/www/revsol.html, followed by
http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2. The feature of
the slash escape allows JSON to be embedded in HTML (as SGML) and XML.
PHP escapes forward slashes by default which is probably why this appears so commonly. I suspect it's because embedding the string "</script>" inside a <script> tag is considered unsafe.
Example:
<script>
var searchData = <?= json_encode(['searchTerm' => $_GET['search'], ...]) ?>;
// Do something else with the data...
</script>
Based on this code, an attacker could append this to the page's URL:
?search=</script> <some attack code here>
Which, if PHP's protection was not in place, would produce the following HTML:
<script>
var searchData = {"searchTerm":"</script> <some attack code here>"};
...
</script>
Even though the closing script tag is inside a string, it will cause many (most?) browsers to exit the script tag and interpret the items following as valid HTML.
With PHP's protection in place, it will appear instead like this, which will NOT break out of the script tag:
<script>
var searchData = {"searchTerm":"<\/script> <some attack code here>"};
...
</script>
This functionality can be disabled by passing in the JSON_UNESCAPED_SLASHES flag but most developers will not use this since the original result is already valid JSON.
Yes, some JSON utiltiy libraries do it for various good but mostly legacy reasons. But then they should also offer something like setEscapeForwardSlashAlways method to set this behaviour OFF.
In Java, org.codehaus.jettison.json.JSONObject does offer a method called
setEscapeForwardSlashAlways(boolean escapeForwardSlashAlways)
to switch this default behaviour off.