AngularJS and PHP: escaping and unescaping JSON string

1.3k Views Asked by At

I was trying to save some data (a table) as JSON in my database with AngularJS and PHP. For that, I would want to convert it to string first and then escape special characters (avoiding SQL injection). Once it's saved, I can retrieve it as a string from DB, convert it back to JSON and display in HTML. To simplify it, let's ignore the database and just return the JSON.

The problem occurred with conversions. Just sending string version of JSON, receiving it as is, and parsing it back from string would result in a string. E.g.

var data = {
  "json": JSON.stringify({"A": "B"})   // some random JSON
};
$http.post("php/sendJSON.php", data).  // AJAX post request
then(function(res) {
  console.log( res.data );             // response from back-end
  console.log( JSON.parse(res.data) ); // parsing it to an object
});

and my back-end:

<?php
$postdata = file_get_contents("php://input");
$res = json_decode($postdata);

$json = $res->json;
echo json_encode($json);
?>

My both logs printed ""{\"A\":\"B\"}"" and "{"A":"B"}". So the parsed response had double quotes and JSON.parse didn't turn it into an object. A hack would be to use JSON.parse(JSON.parse(res.data)), but I was wondering if there is a proper way. (Same thing for angular.fromJson(res.data))

Beyond that issue I was interested in escaping the string. (I used mysqli::real_escape_string) But that would add more complexety to parsing. E.g. this time it will be ""{\\\"A\\\":\\\"B\\\"}"" and "{\"A\":\"B\"}" in logs. So I tried to manually unescape it with:

function unEscapeJsonString($value) {
  $escapers = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
  $replacements = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
  $result = str_replace($escapers, $replacements, $value);
  return $result;
}

This finally gave me an object, but once again it felt like a hack, and unescaping still doesn't solve the problem with a double JSON.parse that I needed to use.

The biggest issue with this is when I try to have new lines and white spaces in JSON, {"A":"B \n C"}, it will not parse it twice and always return a string. Another hack for this is to use:

JSON.parse(res.data).replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");

So the question is: What is the correct way of sending JSON as a string, escaping it, and parsing it back to JSON? (Requests: AngularJS -> PHP -> AngularJS)

0

There are 0 best solutions below