I've spent the last few days trying to get around this problem. Every time I try to get a JSON object using Angular's $http.get, I get "Error: JSON.parse: unexpected character".
My JSON is created using the PHP's json_encode. The PHP code is the following:
header('Content-Type:application/json');
echo json_encode($to_encode);
The JSON it creates looks like this:
{"id":"1","para":{"para_id":"1","story_id":"1","para_content":""\u017bagiel na horyzoncie!" - s\u0142ycha\u0107 krzyk z bocianiego gniazda. Fregata Jego Kr\u00f3lewskiej Mo\u015bci "Acanta" \u017cwawo sunie przez b\u0142\u0119kit oceanu. Ty, jej dow\u00f3dca, stoisz na rufie. Bosman i sternik patrz\u0105 si\u0119 na ciebie, oczekuj\u0105c rozkaz\u00f3w."},"tunnels":[{"tunnel_id":"1","start_para_id":"1","end_para_id":"2","tunnel_content":"Spokojnie, zbli\u017cmy si\u0119 i sprawd\u017amy, kto to."},{"tunnel_id":"2","start_para_id":"1","end_para_id":"3","tunnel_content":"Bi\u0107 na alarm! Za\u0142oga do dzia\u0142!"}]}
(It's UTF8-encoded Polish, if it's relevant; the text is just a placeholder)
The JS that gets it look like this:
$scope.current_para = $http.get("/gamebook/run");
$scope.current_para.then(function(os){result = os.data; console.log(result);}
Instead of a neat JSON in my console.log, I get the error, even though my Firebug tells me that the GET method was successful and even shows me the JSON it received.
I've finally found a workaround to this problems - I still don't know what or why happened, but here's what could be done.
On the server side you have to wrap your JSON data in single quotes (making it a string) then use eval() in JS to turn it back into JSON.
I know it's not elegant, but that's the only solution I've found. Hope it'll help someone.
Thanks everyone for the input!
Related
Good morning everyone and thank you in advance for any suggestions. I have written a small web application to perform simple searches in a stamps database using php and javascript.
The server sends to the browser the whole database as a JSON and the queries are done client-side with a javascript code.
The JSON has this structure:
{"ck":0,"db":[["string11","string12","string13"],["string21","string22","string23"], etc... } .
Until now the system has worked perfectly and over 1500 stamps could be shown.
Suddenly it stopped working and, in the browser's Javascript console, this error message appeared:
VM672:1 Uncaught SyntaxError: Expected ',' or ']' after array element in JSON at position 97506 at JSON.parse (<anonymous>) ...etc...
After a series of tests, by exclusion I came to discover that it was the word "annullo" in the last added record to generate the error.
I guess it could be the substring "null" to give problems, but I have no idea how to escape it.
A really strange thing is that, whilst failing with the JSON.parse() function, browser's javascript console, as well as other json validation tools, recognise the server's response as a valid JSON.
Thanks for any help!
As #Andrea Soffiantini pointed in a comment, this was the actual problem:
Client side I had this command a few lines before parsing: data = data.replaceAll("null","\"\""); , where data is the json as a string, as received from server.
This replaces the string "anullo" with "a""o", which is invalid in JSON syntax.
I think I understand the problem. All strings are enclosed in quotes.
{example: "example"}
In the development of this case they must have put "annullo" but they forgot to insert the quotes. If it was null, not a string, it could look like this, without quotes.
json = {example: null}
However, as annullo is an invalid word in javascript and is not as a string, it gives an error.
The correct thing to do is to correct the error in the source, transforming it to null, however, I believe that you can also use this regular expression. But do tests to ensure that there is no undue substitution elsewhere.
json.replace(/.+["']: ?annull(o|are)[\n,}]$/g, matched => {
return matched.replace(/annull(o|are)/, 'null')
})
My code is having XSS Scripting vulnerability and i want to prevent that. I am using a Jquery Encoder to prevent XSS Scripting .
Following is the JS Code.
function test(response)
{
$('#test').html( $.encoder.encodeForHTML(response));
}
The Contents of the response is this
response="<html><body><table><tr><td>DATA1</td><td>DATA2</td></tr></table></body></html>"
so when i do $.encoder.encodeForHTML(), i expected the output will be a Table (Before using the encoder i was properly getting a table format), but now, the response string itself is getting printed inside the div element.
Can Someone please help me with this.. I need to encode the response (which contains a HTML Code) as such, so that i get the Output as a proper table format.
Am i going wrong somewhere or am i using a wrong function to encode? Suggestions Welcome.
Just use var encodedData = encodeURI(htmlDataToEncode); before you pass it as a response.
I have been working on my project where I had to do some updates on my data records. After I finished my update I got an error: SyntaxError: identifier starts immediately after numeric literal and this line of code was below that error in firebug : maxScores.ew-19a = ''
I looked up in my code and I found where is this output coming from, here is the code:
var maxScores = new Object;
<cfoutput query="getRec">maxScores.#LCase(tCode)# = '#maxScore#';</cfoutput>
In my update I had to put - symbol between letter and number, in old data I did not have that so I think that causing the problem here. I was wondering how I can prevent this or if there is any method that I have to put around my output to prevent this? If you know how this can be fixed pleas let me know. Thank you.
ColdFusion will attempt to subtract ew from 19a when you just dump it between to pound signs like that. You will need to use bracket/object notation here. Try this:
<cfoutput query="getRec">
maxScores.#LCase(getRec["tCode"][currentrow])# = '#getRec["maxScore"][currentrow]#';
</cfoutput>
If you want to Lower case something do it in the query. Outputing JS using CF is useful and solves many problems, but you want to keep it as clean as possible to keep your brain from fogging over. :)
Here's a simplified PHP side of my ajax context:
// in a for loop
$text = "/home/ubuntu/CANE-HDD-100/y.txt"
// $text_encoded = urlencode($text);
// $text_encoded = preg_replace("/(\-)/", "%2D", $text_encoded);
$text_encoded = "%2Fhome%2Fubuntu%2FCANE%2DHDD%2D100%2Fy.txt"
$structure[$i] = $text_encoded;
echo json_encode($structure);
And here is the JS side:
request.onload = function()
{
var cleanedText = JSON.parse(this.responseText);
alert(cleanedText);
};
That throws the following error:
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
If I substitute JSON.parse(this.responseText) with decodeURI(this.responseText), I get cleanedText equal to
/home/ubuntu/CANE-HDD-100/y.txt
["%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"]
which I dislike, since an hypotetic for loop on cleanedText would treat every element of that variable (correctly) as a character, while I'd obviously like to get elements as whole URLs.
A possible, dirty workaround is to set up some regex on cleanedText to recover every URL, but I'm wondering if there would be a much cleaner way.
w3re's comment has to be correct. You must have malformed JSON. We can show this by taking the output you do get from decodeURI, running it back through encodeURI to get what must therefore be your original string from PHP, and then trying JSON.parse on it. We get an error:
JSON.parse(encodeURI('/home/ubuntu/CANE-HDD-100/y.txt ["%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"]'))
(program):1 Uncaught SyntaxError: Unexpected token /
That error is from Chrome, but the :1 is saying 'line 1' and the / is at column 1, so I think that's the error you're seeing.
Basically, this string is not valid JSON, because of the all the stuff at the start which is not wrapped in quotes.
However, for example, this will work, if you put it all in quotes and escape the existing ones:
JSON.parse('"/home/ubuntu/CANE-HDD-100/y.txt \\"%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt\\""')
or using an array:
JSON.parse('["/home/ubuntu/CANE-HDD-100/y.txt", "%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"]')
or an object:
JSON.parse('{"/home/ubuntu/CANE-HDD-100/y.txt": "%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"}')
so something must be going awry in your PHP or JavaScript in and amongst your JSON encoding and decoding. To help further, I'd need to see more of your code.
i have the following button :
<button onclick='enroll(<?php echo $course['cs_id']; ?>)'>enroll</button>
when the user click on it the following javascript function will start :
function enroll(id){
$.post("<?php echo base_url().'courses/enroll/'; ?>"+id , function(data){
obj = JSON.parse(data);
alert(obj.state);
});
}
which perform a post request to php page which echo json array like this :
$data = array("state"=>"done");
die(json_encode($data));
but unfortunately the following error appears in the console :
JSON.parse: unexpected character
i checked the page response and its look like this (which seems fine ) :
{"state":"done"}
also when i change the enroll() function to be like this :
function enroll(id){
$.post("<?php echo base_url().'courses/enroll/'; ?>"+id , function(data){
alert(data);
});
}
its show the alert message correctly like this :
{"state":"done"}
so why it refuse do parse the response where everything seems okay ? any idea ?
My guess is that your code is actually working better than you think! I think that jQuery receives your JSON from the server and realises that it is JSON, even though you haven't specified it as such. (Perhaps your PHP is sending a Content-Type header?)
So data is actually already a Javascript object, which jQuery has decoded from your JSON. When you call JSON.parse on an object, it is converted to a string [object Object], and then parsed. [object Object] is evidently invalid JSON, hence the unexpected character error.
Since the string was obviously valid JSON, my next guess was that there was some data before the string that was causing the parser to be unhappy. The best way to test this is with String#charCodeAt, which reveals the precise character at a given point in the string.
So, with the following code, we can test to see what the first character in the string is:
console.log(data.charCodeAt(0));
You say that this returns 65279, which, at the beginning of a Unicode document, is a byte order mark. You are apparently outputting this somewhere in your server-side code. You need to find out where that is and remove it.
Do not parse the data again:
function enroll(id){
$.post("<?php echo base_url().'courses/enroll/'; ?>"+id , function(data){
alert(data.state);
});
}