JSON html string is not being converted to html by innerhtml - php

I am using javascript and php and need to pass some HTML in the JSON variable (PHP->JS).
Unfortunately, due to some environmental constraints I am limited in the jQuery I can use. Using things such as jQuery.parseJSON(str) and $.parseJSON(str) throw unexpected token errors.
Therefor I need a purely javascript approach to handling html in a JSON variable. Currently, the HTML string is just printed as a string on the page, though I need it to take effect as HTML.
My JS code is as follows:
document.getElementById("activeDescription").innerHTML = response['description'];
and the results ends up just being text on the HTML page as follows:
<p>helloworld</p>
whereas I expect just
helloword
to be displayed on the HTML page. On alert(response['description']) I receive
<p><span class="
EDIT
When I use
jQuery.parseJSON('{"name":"John"}');
everything is peachy but this code
jQuery.parseJSON(response['description']);
gives me an "Uncaught SyntaxError: Unexpected token & " error

Most probably a encoding problem. You can fix by decoding the characters.
In javascript:
var div = document.createElement('div');
div.innerHTML = encoded;
var decoded = div.firstChild.nodeValue;
In PHP, look at this link: http://www.php.net/manual/en/function.htmlentities.php

Related

Difference between echoing json_encode and returning it in ajax

I think this may be classified as basic but I was curious. Why do you have to parse json encoded data returned from ajax calls but not if it is echoed by php in the main loading document?
Edit: Basically the question is, if I have an object called data with a property id in both cases, why I can type
data.id
and have the value returned when the json object has been echoed out while loading the main document, but have it throw an error when returned from an ajax call and not parsed?
By echoed, I assume you mean you did something like this:
<script>
var data = <? echo json_encode($data) ?>;
alert(data.id);
</script>
If that's the case, the browser knows that the echoed json is code because it's contained by script tags. JSON is a subset of JavaScript, so what you're really doing here is generating JavaScript code that the browser then interprets.
Ajax, on the other hand is different. When you load something with ajax, it might be text, xml, csv, html, svg, or any of dozens of different formats. JSON is just a data format like all the others I listed, so you've got to tell the javascript engine what it is. That's why you have to parse it. It needs to know the format of the text so it can interpret it correctly.
You don't have to, and JSON-encoded strings still need to be "decoded" from Javascript. It's just a faster way of being able to access array elements/properties in the returned string for ajax calls.

Good JSON but browser throws error

I have a PHP script that is building the header portion of an HTML(5) document. Part of what is being emitted is something like this
$rtn = <<<RTN
<script type='text/javascript'>
var _scrolls = {"alpha":{"cursorborder":"1px dashed rgba(200,13,57,1)"}};
var _floors = new Array(10000,{$mqt},{$mqf});
</script>
RTN;
The JSON is valid - at least, JSONlint.com seems to think so. However, in my browser (Chrome on Windows) this throws up an error Uncaught Syntax Error: Unexpected token illegal.
By dint of some experiment I have narrowed down the problem to the last attribute
"cursorborder":"1px dashed rgba(200,13,57,1)"
For some reason the browser is taking exception to the spaces in the attribute value. If I collapse that string so that it reads
"cursorborder":"1pxdashedrgba(200,13,57,1)"
the syntax error message disappears. I cannot think of any rational explanation for this. For completeness I guess I should mention that the JSON is being generated server side courtesy of json_encode.
Perhaps someone out here can tell me where I am going wrong?
it doesn't throw an error if I remove the first and the last ' , like this:
var _scrolls = {"alpha": {"bouncescroll":true,"boxzoom":false,"enabletranslate3d":true,"dblclickzoom":true,"gesturezoom":true,"hwacceleration":true,"horizrailenabled":true,"enablekeyboard":true,"railalign":"right","enablemousewheel":true,"nativeparentscrolling":true,"enablescrollonselection":true,"sensitiverail":true,"smoothscroll":true,"spacebarenabled":true,"railvalign":"bottom","touchbehavior":false,"autohidemode":false,"cursorcolor":"rgba(245,146,30,1)","background":"rgba(127,255,142,1)","cursorborder":"1px dashed rgba(200,13,57,1)"}};
You can't have literal line breaks in a JavaScript string literal.
Remove or escape them. Better: don't use JSON for this and just have a JavaScript object literal, that will save you from having to have a separate parse step.
As Jonas said, remove the ' from the beginning and the end of the string.
That way, the variable will become a valid Javascript Object and not just a long string containing JSON.

php htmlspecialchars and jquery .text()

I ran into an issue recently. I have a system where users can post stuff. One of the fields is the title field. So to save user input safely I use htmlspecialchars on the user submitted title and send it to a function that then saves to the database (after using mysql_real_escape)
Now on the client's side I use json get to fetch this title
$.getJSON("PHPFILE", function(json) {
// let's say json.title is the title we need so...
var title = json.title;
}
Now the thing is this user given title value can contain anything, even html tags (for reference let's say it now contains
<script>alert('');</script>Some Text!
so since I use jquery I thought of clearing those using the .text() function
var cleanTitle = $(title).text();
alert(cleanTitle);
However this immediately throws an error. In chrome it says
Uncaught Error: Syntax error, unrecognized expression ...
So I verified if this title variable is a string. And it is indeed a string. (Btw for some reason if this variable contains only numbers there is no error)
Using the following however gives me the text but the tags aren't removed
var cleanTitle = $.parseHTML(title);
cleanTitle = $(cleanTitle).text();
alert(cleanTitle);
This outputs
<script>alert('')</script>Some Text!
How can I remove all html tags? Any suggestions? I am planning to use this title text to set Browser title. Thanks.
document.title = $('<div />').append( $('<div />').html( title ).text() ).text();
Appending the string twice should fix the htmlentities issues.
Since you are using MySQL as engine to store that kind of data, you are clearly using PHP scripting. Suggestion: use PHP's strip_tag() and you are cutting "workload" for jQuery/Javascript by letting PHP do the work.

JSON array to PHP / MySQL JSON.parse JSON.stringify how to store double quotes and single quotes

I have a form with fields and a text-area that allows any characters to be entered. I can't just submit the form, because the form is being recycled many times over, so the form values are being stored in associative arrays:
<form name='Theform'>
<input type="text" id="VISITOR_DETAILS_NAME" value="Joe">
<input type="text" id="VISITOR_DETAILS_SIZE" value="Large">
<textarea id='VISITOR_DETAILS_INFO'>
User can enter anything here including double " and single ' quotes
</textarea>
<input type="hidden" name="package" id="package" value="" />
</form>
The text-area value are stored in a JavaScript array along with the other form values:
myArray[0]['VISITOR_DETAILS_NAME'] = document.getElementById('VISITOR_DETAILS_NAME').value;
myArray[0]['VISITOR_DETAILS_SIZE'] = document.getElementById('VISITOR_DETAILS_SIZE').value;
myArray[0]['VISITOR_DETAILS_INFO'] = document.getElementById('VISITOR_DETAILS_INFO').value;
I end up with an array something like this:
{
VISITOR_DETAILS_NAME : "Joe",
VISITOR_DETAILS_SIZE : "Large",
VISITOR_DETAILS_INFO : "User can enter anything here including double " and single ' quotes"
};
I then pass this JavaScript array to the hidden form field using JSON.stringify and then POST this to PHP:
document.getElementById('package').value = JSON.stringify(myArray[0]);
Theform.submit();
(For now I'm just posting to an iframe to test that the JSON is passing the JavaScript arrays properly through POST).
When I get it on the PHP side - it seems good to go. It looks like the JSON.stringify has added the backslash to the double quote (\" ) - and now I want to store the values in MySQL. But I want to first test that I can send/reconstruct the JSON back to the javascript as an array - so I try this:
parent.myArray[0] = JSON.parse('<?php echo $_POST['package']; ?>');
I get an ERROR: SyntaxError: Expected token ')' OR SyntaxError: missing ) after argument list
This is strange to me - because when I try it without POSTING - It seems to work fine like this:
document.getElementById('package').value = JSON.stringify(myArray[0]);
now if I try to just pass back the stringified value back to the array
myArray[0] = JSON.parse(document.getElementById('package').value);
- it seems to work fine - no errors
QUESTIONS:
Why am I getting this error when trying to reconstruct the ARRAY from the
POSTED JSON.stringify() value?
Do I save this JSON.stringify() value in MySQL as is?
Or do I PHP json_decode() it first?
I want to grab the form data - handle it properly - store it in MySQL and then read it back into the form when I need it.
Thanks All :)
parent.myArray[0] = JSON.parse('<?php echo $_POST['package']; ?>');
Here you are are trying to convert a JSON text into an HTML representation of a JavaScript string representation of a JSON text, but you aren't doing anything to escape it for either.
If you have any ' characters in the JSON data, then they will terminate the JavaScript string.
If you have any " characters in the JSON data, then they will be represented as \", but \" is a JavaScript string representation of ". Since you don't do anything to escape the text you put in the JS string, the slash character will be consumed by the JavaScript parser and will be gone before it reached the JSON parser.
If you want to convert data for placing in a JavaScript string then you need to escape it.
However, JSON is a subset (almost) of JavaScript. So the process of converting a JSON text to a JavaScript string so it can be parsed into a JavaScript object is over-complicated. You can skip that can just go straight to:
<script>
var foo = <?php echo $json; ?>
</script>
However, since you are taking in the JSON from the client, echoing out directly will expose you to XSS attacks. In order to deal with this you should filter the data on the server.
This will:
Fail to parse any invalid JSON and so not output bad JSON (but it might output nothing, giving you a JSON syntax error, you should apply tests to see if the parse was successful and output a sensible default case if it fails).
Convert any </script> in the data to <\/script> making it safe to place in a script element (because that is how PHP's json_encode works
Such:
<!-- I don't do PHP, this is untested -->
<script>
var foo = <?php
$unsafe_json = $_POST['package'];
$data_structure = json_parse($unsafe_json);
$safe_json = json_encode($data_structure);
echo $safe_json;
?>;
</script>
Do I save this JSON.stringify() value in MySQL as is? Or do I PHP json_decode() it first?
That depends on what you intend to do with the data. In general when putting things into a database it is a good idea to extra the data from the data format and normalize it. That way you can run queries over it.
If you are only going to store the data and then retrieve it, you might be able to get away with not doing that and storing strings of JSON in the database. That loses you a lot of flexibility though and might bite you in the future.

json_encode won't escape newlines

Firstly, I have search Stack Overflow for the answer, but I have not found a solution that works.
I am using an MVC framework (yii) to generate some views and throw them in an array. Each view is a card, and I have an array of cards ($deck) as well as an array of arrays of cards ($hands, the list of hands for each player). I'm simply trying to set a javascript variable on the front-end to store the hands created in PHP. My view has, it is worth noting, multiple lines. In fact, my current test view consists only of:
test
test
I therefore used json_encode, but it's giving me the following error when I use $.parseJSON():
Uncaught SyntaxError: Unexpected token t
I read elsewhere that it is required (for whatever reason) to use json_encode twice. I have tried this, but it does not help.
With a single json_encode, the output of echoing $hands (followed by an exit) looks pretty healthy:
[["test\ntest","test\ntest","test\ntest","test\ntest", etc...
But when I do not exit, I get a syntax error every time.
Edit: Here is a sample of my code. Note that $cards is an array of HTML normally, but in my simplified case which still errors, includes only the two lines of 'test' as mentioned above.
$deck = array();
foreach ($cards as $card) {
$deck[] = $this->renderPartial('/gamePieces/cardTest',
array('card'=>$card), true);
}
$hands = Cards::handOutCards($deck, $numCards , $numPlayers);
$hands = json_encode($hands);
echo $hands; exit;
With JavaScript, I am doing the following:
var hands = $.parseJSON('<?php echo json_encode($hands); ?>');
It errors on page load.
Any help would be appreciated!
Thanks,
ParagonRG
var hands = $.parseJSON('<?php echo json_encode($hands); ?>');
This will result in something like:
var hands = $.parseJSON('{"foobar":"baz'"}');
If there are ' characters in the encoded string, it'll break the Javascript syntax. Since you're directly outputting the JSON into Javacript, just do:
var hands = <?php echo json_encode($hands); ?>;
JSON is syntactically valid Javascript. You only need to parse it or eval it if you receive it as a string through AJAX for instance. If you're directly generating Javascript source code, just embed it directly.

Categories