-2

I have a JSON that is getJSONed to a PHP script in order to update the database for a simple CMS:

 {
    "pid": "3",
    "post": "<p><span style='text-decoration: underline;'><strong>Test</strong></span></p><br><p>blah</p><br><p>&nbsp;</p><br><p><span style='text-decoration: underline;'><strong>Test</strong></span></p><br><p>blah</p>",
    "tagline": "",
    "title": "About"
 }

In PHP it is decoded with json_decode and then sent off to the database.

It works perfectly and JSONLint reports that the JSON is valid, however PHP's json_decode fails with error 4, which is 'syntax error'. I'm unsure which is correct (I copied the JSON above from the GET request I send, so should be valid on JS' side).

I use JSON.stringify to create the JSON from my array on JS' side. The array is as follows:

var arr = {
    pid : "<?php echo $pId; ?>",
    post : $("#edit_target_preview").html(),
    tagline : document.getElementById('page_tagline').value,
    title : document.getElementById('page_title').value,
};

This array is forwarded to the PHP script via getJSON:

$.getJSON("savepost.php?json=" + JSON.stringify(arr), function(data){
    *stuff happens here*
});

What am I doing wrong here? Am I overthinking this, or using completely the wrong approach?

Hexdump:

7b22706964223a2233222c22706f7374223a223c703e3c7370616e207374‌​796c653d5c2274657874‌​2d6465636f726174696f‌​6e3a20756e6465726c69‌​6e653b5c223e3c737472‌​6f6e673e546573743c2f‌​7374726f6e673e3c2f73‌​70616e3e3c2f703e3c62‌​723e3c703e626c61683c‌​2f703e3c62723e3c703e

AStopher
  • 4,207
  • 11
  • 50
  • 75
  • Use your browser's console, network tab: please share the response/preview of the "savepost.php" request. Sometimes a blank space or an error in the php script will interrupt the json string. – Ofir Baruch Jan 29 '17 at 20:59
  • 1
    after the replace you JSON string becomes: `"{
    "pid": "3",
    ...` which is not valid JSON.
    – ibrahim mahrir Jan 29 '17 at 21:00
  • There's something wrong but you do seem to be overthinking it. Make a simple php file that shows the behaviour. Capture the actual GET info and hardcoded it in a variable. Then json_decode it, showing the error. Then post that here! 9 out of 10 says yo uwill find the bug, otherwise we can help you debug :) – Nanne Jan 29 '17 at 21:01
  • @OfirBaruch It's 200, in PHP I return a JSON to give a result whether the database update was a success or not, so that always gives `[{"valid":"0"}]`. There are no errors reported either onscreen or PHP's log file, apart from `echo json_last_error();` returning `4` (as mentioned). – AStopher Jan 29 '17 at 21:01
  • Must be something else: https://3v4l.org/AJ8bE – AbraCadaver Jan 29 '17 at 21:03
  • @ibrahimmahrir I perform the replace on just the HTML string; the JSON in my question is from a `console.log` in JS of the `JS.stringify`'d array. The return within that is simply me formatting it for the question. The actual JSON is one line. – AStopher Jan 29 '17 at 21:03
  • @Nanne I confirm that copying & pasting the JSON directly into PHP works fine. That rules out PHP being at fault here. – AStopher Jan 29 '17 at 21:07
  • This is still vague. Where do you replace the newlines? On PHP side or on JS side? And is it before or after the decoding? – ibrahim mahrir Jan 29 '17 at 21:08
  • How did you copy-and-paste it? maybe some of the newlines are actually `
    `, but you copied them from the browser? try using `var_dump` on the variable you get when it doesn't work and copy that, or better, read it from an error file (and not a browser), or use the source of the page. Anyway, try and make a minimal http://sscce.org/
    – Nanne Jan 29 '17 at 21:09
  • @ibrahimmahrir Everything's in the question, including why I replace the newlines (JSON does not support multiline strings, so newlines must be replaced). – AStopher Jan 29 '17 at 21:09
  • Post your PHP code because it's there where the problem is. Because if it was on JS side then `JSON.stringify` will throw an error. – ibrahim mahrir Jan 29 '17 at 21:10
  • @Nanne The [mcve] there is the best I can do. There's no errors generated apart from the `4` output from `json_last_error` which signifies a syntax error. – AStopher Jan 29 '17 at 21:10
  • @ibrahimmahrir We've already established that this has nothing to do with PHP (unless `json_decode($_GET["json"], true)` has a fault). This issue *only* occurs if there is a newline, so almost definitely on JS' side, but the question I suppose is *what* is causing it to behave in this way? – AStopher Jan 29 '17 at 21:11
  • Where does the silly "JSON is unable to handle multiline strings" assumption come from? And where's the hexdump of the JSON as received by PHP? – mario Jan 29 '17 at 21:12
  • I'm sorry, but I don't see a 'verifiable example' here, there's nothing I can run, so while I hope you figure it out, I'm not going to be able to help you much like this. Good luck – Nanne Jan 29 '17 at 21:12
  • @mario [Here](http://stackoverflow.com/a/16690236/2422013). I'll get the hexdump. – AStopher Jan 29 '17 at 21:14
  • So, uhm, `\n` is perfectly valid in JSON. Still don't get how this is relevant. – mario Jan 29 '17 at 21:16
  • @mario `7b22706964223a2233222c22706f7374223a223c703e3c7370616e207374796c653d5c22746578742d6465636f726174696f6e3a20756e6465726c696e653b5c223e3c7374726f6e673e546573743c2f7374726f6e673e3c2f7370616e3e3c2f703e3c62723e3c703e626c61683c2f703e3c62723e3c703e`. You're right, unsure why I put that. Will modify. – AStopher Jan 29 '17 at 21:16
  • Post it in the question please. The comment's too long really, and the Unicode fillers don't help. Also, naturally, you should generate a hexdump of the PHP variable, not from the URL or any other copy+paste source. – mario Jan 29 '17 at 21:21
  • @mario I *did* generate a hexdump from PHP (used `bin2hex`- `echo bin2hex($_GET["json"]);`). – AStopher Jan 29 '17 at 21:24
  • The excerpt you posted is just 120 bytes and ends prematurely. Go investigate who cut it off. – mario Jan 29 '17 at 21:27
  • @mario I think I have it now. Seems to cut off at `nbsp;`, so it looks like HTML entities are a problem. Investigating [this answer](http://stackoverflow.com/a/5796744/2422013) and will close my question as a duplicate if that does solve the problem. Nice suggestion with the hexdump by the way, I wouldn't have thought of that myself. – AStopher Jan 29 '17 at 21:31
  • Well, in retrospect, really needs URL encoding if you manually construct the URL. – mario Jan 29 '17 at 21:32

2 Answers2

4

You're missing a call to encodeURIComponent (or the use of a decent serialiser) when composing you're URL. As your JSON contains a &, decoding on the server will truncate your data. It would have been obvious if you had logged the data before json_decode.

Note that it's most probably NOT a good idea to pass your JSON in the URL in a GET request (due to length restrictions). I'd strongly recommend using a POST request, which would also make a lot more sense semantically.

jcaron
  • 17,302
  • 6
  • 32
  • 46
1

Since you're using getJSON which :

Load JSON-encoded data from the server using a GET HTTP request.

This &nbsp; is causing error, the JSON ends just before it at <p>, since you're doing a GET request and & marks the end of the previous parameter and the beginning of another parameter...

Just use post instead and it should work:

$.post("savepost.php", {json :  JSON.stringify(arr)}, function(data) {
    // Do something here
}, 'json');
mrbm
  • 2,164
  • 12
  • 11