可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm using Grails 2.3.7 and I have a controller action as follows:
def testData(){
def result = [:]
result['name'] = "Sales"
result['type'] = "bar"
result['data'] = [5, 20, 45, 10, 10, 20]
[data: result as JSON]
}
In the testData.gsp I'd like to get the JSON object in javascript:
<script>
$(document).ready(function(){
var data = JSON.parse(${data});
})
</script>
Then I got an exception:
Uncaught SyntaxError: Unexpected token {
on the line:
var data = JSON.parse({"name":"Sales","type":"bar","data":[5,20,45,10,10,20]});
It looks like JSON is messed up. I think it used to work this way. Maybe it's new Grails? How can I fix this? Thanks.
Update:
Problem solved. See the comments in the accepted answer.
Update2:
When I check the app today, it failed again. I did what the docs required with the "raw" method but no luck. A workaround is to use the "Per Page Encoding". This one I tested thoroughly. It does work.
回答1:
The problem is that the JSON is being encoded as HTML. Try the following instead:
Controller
def testData() {
def result = [:]
result['name'] = "Sales"
result['type'] = "bar"
result['data'] = [5, 20, 45, 10, 10, 20]
[data: result as JSON]
}
GSP
<script>
var data = ${raw(data)};
</script>
You don't need $(document).ready
because the JS code
var data = ${raw(data)};
is generated on the server-side
回答2:
Working solution :
def action() {
[data: data as JSON]
}
GSP page:
<g:applyCodec encodeAs="none">
var data = ${data};
</g:applyCodec>
回答3:
The encodeAsJSON()
method works well for outputting JSON data into JavaScript:
Controller
def testData() {
def data = [name: "Sales", values: [5, 20, 45]]
[data: data]
}
View (GSP)
<script>
var data1 = ${raw(data)}; //{name=Sales, values=[5, 20, 45]}
var data2 = ${raw(data as grails.converters.JSON)}; //{"name":"Sales...
var data3 = ${data.encodeAsJSON()}; //{"name":"Sales","values":[5,20,45]} CORRECT!
</script>
Using raw()
on a Groovy object does not produce JavaScript compatible output (see data1
), and using it after the JSON converter results in unwanted "
encoding (see data2
). Using encodeAsJSON()
produces the correct output (see data3
).
Documentation:
http://grails.org/doc/latest/guide/security.html#codecs
Update:
I've switched to using a taglib with:
out << "<script>var data = " + raw((data as JSON) as String) + ";</script>"
回答4:
Not all grails versions support raw() method or g:applyCodec taglib.
The solution is to use <%= %> block to avoid escaping
<%= users.collect({id:it.id,value:it.name}) as grails.converters.JSON%>
OR
<%= someJsString.encodeAsJavascript() %>
But best practice is to avoid using serverside generated JSON into GSP and refactor into getting the same JSON received via ajax request
回答5:
The following worked for me using Grails 2.4.3:
Controller:
def result = [:]
result['type'] = "bar"
result['data'] = [5, 20, 45]
model: [data: result as JSON]
GSP:
<script>
// this worked!
var data = ${raw(data as String)};
</script>
Produced desired result:
<script>
// this worked!
var data = {"type":"bar","data":[5,20,45]};
</script>
The accepted answer by Dónal DID NOT work for me:
Controller (same as my working example above)
GSP (did NOT work):
<script>
// did NOT work!!
var data = ${raw(data)};
</script>
Produced same bad result:
<script>
// did NOT work!!
var data = {"type":"bar","data":[5,20,45]};
</script>
回答6:
This worked for me in grails 3.1.9.
Controller:
def result = [:]
result['type'] = "bar"
result['data'] = [5,20,45]
result['key'] = token
[data:result as JSON]
GSP:
<script>
var data = '${raw(data as String)}';
var json = JSON.parse(data);
alert(json.type);
var authorization = json.key;
</script>
回答7:
In testData.gsp add
<%@page expressionCodec="none" %>
and in script
<script>
$(document).ready(function(){
var data = ${data};
})
</script>
回答8:
This might also help, passing data as simple model and parsing it as JSON in gsp.
def testData() {
def result = [:]
...
[data: result]
}
On View
<%! import grails.converters.JSON %>
...
<script>
function parseModelToJS(jsonString)
{
jsonString=jsonString.replace(/\"/g,'"');
var jsonObject=$.parseJSON(jsonString);
return jsonObject
}
$(document).ready(function(){
var data=parseModelToJS('${data as JSON}');
console.log(data);
});
</script>
http://www.oodlestechnologies.com/blogs/Parse-model-to-json-on-gsp-in-grails
回答9:
You can do this,
import groovy.json.*
Map testMap = ['name': 'Test']
String jsonData = new JsonBuilder(testMap).toPrettyString()
render(view: view, model: ["data": jsonData], params: [:])
In your gsp:
<script>
var data = ${raw(data)};
</script>
Simple..