Good JSON but browser throws error - php

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.

Related

How to fix “unsupported pseudo” error of jQuery AJAX?

I am trying to get response from a php page using jQuery Ajax. Everything works fine until I tried to explode an array and combined it elements to get a time 09:00.
Console says, Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: 00 and nothing displayed.
My code is,
$starttimeArr= explode(",",$comma_separated_starttime);// explodes 09,00,00
$endtimeArr= explode(",",$comma_separated_endtime);// explodes 17,00,00
echo $starttime= $starttimeArr[0].":".$starttimeArr[1];// combine to get 09:00. The line pop up the error
$endtime= $endtimeArr[0].":".$endtimeArr[1];// combines to get 17:00
How did I overcome this error? Any help will be appreciated.
My Ajax code is
jQuery("#_dob").change(function() {
jQuery.ajax({
url: "<?php echo $this->getUrl('deliverybydatepro/index/index') ?>",
data: "checkIn="+jQuery(this).val()+"&type=calendar",
type: "GET",
dataType: "html",
success: function(data) {
var $response=jQuery(data);
jQuery("#div1").html(data);
}
});
});
The response page has a dropdown having an option "09:00". jQuery-1.8.0 triggers an error on it.
Okay. Having seen the edited question with the JS code, the problem is clear:
var $response=jQuery(data);
This line is the cause of the error.
The data variable is the response string from the AJAX request. This contains the string "09:00", as expected.
This means that your code is equivalent of calling jQuery('09:00').
jQuery will try to interpret that as a CSS selector. It will see the 09 and try to find an element with that name. It won't find one of course, but it won't complain about that. However it will then see the :00 and assume that's a pseudo-selector (like :before or :first-child, etc). Of course :00 is not a valid pseudo-selector, and jQuery will complain about that. So that's where the error is coming from.
So what to do about it? Well the answer is quite simple, really.
You're using this line to set a variable called $response, but then you're never using that variable; you're continuing to use the data variable. So really the whole of the line that is throwing the error is completely unnecessary. You may need a line like that if your PHP is outputting JSON or XML data, but not if it's a plain string.
So the solution is to remove that line entirely.
Hope that helps.
Just as an aside, to help you out for next time, it would have been fairly easy to find out which line of JS code was causing the problem by using the debugger in the browser. Just open the Dev Tools or Firebug, and run the code, and it would stop and show you exactly where the error is. A little bit of further work with the debugger looking at variables, and it would probably have become clear what the problem was.
The php-answer is right, it sent the text '09:00' to javascript , but jQuery throws an error: "Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: 00", maybe ajax-answer is used as the determinant of element, maybe other . Show your js-code, because it throws an error
jQuery(data) was taken as the definition of an element with the pseudo-selector '09:00' and say that :00 - unsupported pseudo, becose there is the pseudo-selectors: first-child, hover, active and etc.
In this strings:
var $response=jQuery(data);
jQuery("#div1").html(data);
the string "var $response=jQuery(data);
is not needed, without this string script would work.

JSON html string is not being converted to html by innerhtml

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

Changing servers, and getting SyntaxError: JSON.parse: unexpected character parsererror

I'm moving php code from one linux server to another, and the new one is producing rubbish.
In Firebug, the first result looks great, like normal json encoded values, and works.
The second result (new server) is preceded by "html" and "body" tags, a "p" tag, and then "quot;" instead of actual quotes around the data (sorry, I couldn't get the form to display all that), and throws an error.
In both cases, the code is the same, the output an array passed through json_encode.
Could this be a configuration error?
Thanks in advance.
John
Well, ultimately I added header('Content-type: application/json'); which removed the encoded html. I'd sure like to know why I had to do that.

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.

Problem with mixing Javascript the PHP

I am trying to assign values in javascript assigned from PHP and the use document.write() to output them. The problem is when I do this, a complete blank screen shows up but no errors are ever thrown. But if I take the PHP out and put in a value such as 'ABC' it works. And example of my code can be this:
var comment_text="<?php echo $value['comment_text'];?>";
var bodyelement = document.getElementsByTagName('body')[0];
var newdiv = document.createElement('div');
newdiv.style.textAlign = 'center';
newdiv.style.zIndex = 10001;
newdiv.style.left = (<?php echo $comment_x;?>+getPos('browserwindow',"Left")-23) + 'px';
newdiv.style.top = (<?php echo $comment_y;?>+getPos('browserwindow',"Top")-90) + 'px';
newdiv.style.position = 'absolute';
newdiv.innerHTML = comment_text;
bodyelement.appendChild(newdiv);
I do have an PHP error log and no errors are beign thrown either. The values are retrieved from the database, the probem comes with outputting them.
*UPDATE*
Ok, I had this problem before.
Basically a newline is created like this:
var comment_text="cool Beans
";
I have tried to remove the newline with string replace but doesn't seem to work. Why would a new line like this cause this error?
Your issue is cleary in the output from PHP. If you get a blank page, means you most likely have a PHP issue that is HALTING the processing of said page.
As PHP is parsed before anything is sent to the viewer, this will result in a blank / error page.
When you substitute your $value['comment_text'] for ABC you remove the location that causes the error.
I am going to assume that $value['comment_text'] is either a result of a function, or a Database query, try just outputting the $value['comment_text'] first, then worry about sticking it in JS (which will work if your PHP code works).
As I don't see any of your PHP code, I cannot help you further.
Use
var comment_text=String(<?php echo json_encode($value['comment_text']);?>);
instead of
var comment_text="<?php echo $value['comment_text'];?>";
This will protect you from cross-site-scripting attacks by escaping all special characters like backslashes, quotes or line feeds.
The String(...) ensures that comment_text has type String and is not interpreted as a number (if $value['comment_text'] is has a number type).
If PHP is causing an error (sounds like it is) you can turn on your error reporting to see the issues
error_reporting(E_ALL)
The solution was just using trim.
echo trim($value['comment_text']);
I recommend you use a heredoc for the javascript code with %s in the js. and use sprintf to substitute the variables.

Categories