0

I'm getting the following error when trying to make an ajax request (with Angularjs) to my PHP API.

SyntaxError: Unexpected token n in JSON at position 24

I'd appreciate any help. Thanks

Here is my Angular JS code:

var data = {"username":"sarahexample", "password":"5f4dcc3b5aa765d61d8327deb882cf99"};
$http({
    method: 'POST',
    url: 'http://localhost/API/auth',
    data : JSON.stringify(data)
}).then(function successCallback(response) {
   console.log(response);
}, function errorCallback(response) {
   console.log(response);
});

And here is the PHP auth function which executes when that endpoint is requested.

protected function auth($parameters) {
    if ($this->method == 'POST') {
        //echo the POST data back to the client side to test it's working
        //This works when I take out the php Content-Type header
        echo json_encode($_POST);
    } else {
        //echo "Only accepts POST requests";
    }
 }

In my PHP API I have the following header (which when taken out everything works fine however I'd like it to work with the header).

header("Content-Type: application/json");

I tried leaving in the above header and also adding in contentType: 'application/json' in the ajax request as follows (however this did not solve the JSON error):

$http({
    method: 'POST',
    url: 'http://localhost/API/auth',
    contentType: 'application/json',
    data : JSON.stringify(data)
}).then(function successCallback(response) {
   console.log(response);
}, function errorCallback(response) {
   console.log(response);
});

In the Network tab in the console:

Request URL:http://localhost/API/auth
Request Method:POST
Status Code:200 OK
Remote Address:[::1]:80
Referrer Policy:no-referrer-when-downgrade

Response Headers
view source
Access-Control-Allow-Methods:*
Access-Control-Allow-Origin:*
Connection:Keep-Alive
Content-Length:6
Content-Type:application/json
Date:Thu, 28 Sep 2017 17:17:31 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.27 (Win64) PHP/5.6.31
X-Powered-By:PHP/5.6.31

Request Headers
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:73
Content-Type:application/json
Host:localhost
Origin:http://localhost
Pragma:no-cache
Referer:http://localhost/phonegap_tut/


Request Payload
view source
{username: "sarahexample", password: "5f4dcc3b5aa765d61d8327deb882cf99"}
password
:
"5f4dcc3b5aa765d61d8327deb882cf99"
username
:
"sarahexample"
Sarah
  • 1,943
  • 2
  • 24
  • 39
  • 1
    what is the actual JSON payload you are sending as the body of request...? – Neil Hibbert Sep 28 '17 at 16:48
  • 2
    The symptoms suggest you aren't returning valid json. If you specify that you are returning json from the server, you must return json both on success and error if you want to be able to read the response client-side. – Kevin B Sep 28 '17 at 16:48
  • @NeilHibbert Thanks. Sorry I left that out by mistake. I edited my question adding in the JSON payload – Sarah Sep 28 '17 at 16:56
  • My guess is that your use of [`header`](http://php.net/manual/en/function.header.php) is incorrect in PHP, and that's causing a PHP error to be returned to the client, which error is not valid JSON. – tex Sep 28 '17 at 16:57
  • We need to see what is actually sent, not what you intended to send. – tex Sep 28 '17 at 16:58
  • I have other headers header("Access-Control-Allow-Orgin: *"); header("Access-Control-Allow-Methods: *"); also in the same place in the PHP API which are not causing error. And I followed this tutorial to create the PHP API so I'm 99% sure the headers are correct. http://coreymaynard.com/blog/creating-a-restful-api-with-php/ – Sarah Sep 28 '17 at 17:00
  • How sure are you that said tutorial doesn't have any mistakes? – Kevin B Sep 28 '17 at 17:05
  • @Kevin B 99% sure. 1% unsure.. :P :) – Sarah Sep 28 '17 at 17:07
  • My next guess is that there's an issue with your server's MIME types configuration. [This article](https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Configuring_server_MIME_types) may be helpful. – tex Sep 28 '17 at 17:10
  • Use your browser's Dev console (network tab in chrome) to see what the server is actually sending the client, then let us know what you find out. – tex Sep 28 '17 at 17:17
  • @Tex Thanks I edited my question to show this. – Sarah Sep 28 '17 at 17:22
  • In the Network tab, please click in the 'Response' sub tab and let us know what's there. The headers are helpful, but they're not yet showing us what was returned by the server. – tex Sep 28 '17 at 17:42
  • @Tex Ah ok. It says []null – Sarah Sep 28 '17 at 17:54
  • I think [this](https://stackoverflow.com/questions/9597052/how-to-retrieve-request-payload) is relevant. I don't think`$POST` contains the contents of JSON sent in the request body. It's been a while since I've done much with PHP so I'm a little rusty. – tex Sep 28 '17 at 18:01
  • Oddly enough (before reading your comment) I just remembered coming across that solution before and have just tried it. So now in the response tab I'm getting: {\"username\":\"sarahexample\",\"password\":\"5f4dcc3b5aa765d61d8327deb882cf99\"}"null .... but the data is not coming back in the ajax request. I'm gonna leave it for a while and then continue to try figure it out. Thanks for your help so far. – Sarah Sep 28 '17 at 18:10
  • I added this to the ajax request parameters responseType:'json' and now the successCallback is running in the ajax request thankfully. However when I console.log(response) the data is null as follows {data: null, status: 200, config: {…}, statusText: "OK", headers: ƒ} – Sarah Sep 28 '17 at 18:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/155581/discussion-between-sarah-and-tex). – Sarah Sep 29 '17 at 10:26

2 Answers2

0

I discovered why the error was occuring. There was a combination of a few things.

Firstly there was a silly mistake on my part where I was echoing the data twice by accident:

I have a class called MyAPI.php which contains the auth method. I was echoing the data from here when I should have been returning it as it gets echoed again in another script called api.php. This was adding a null onto the end of the JSON data that the server returned.

So here's my new auth function:

protected function auth($parameters) {
    if ($this->method == 'POST') {
        //need to get the POST data this way because we have the Content-Type header set to application/json, so $_POST will no longer be populated
        $rawPostData = file_get_contents('php://input');
        //return the data because we will echo it from the api.php script
        return $rawPostData;
    }else{
        $errorMessage = array("error" => "Only accepts POST requests");
        return json_encode($errorMessage);
    }
}

And here is the script called api.php which echos the result.

<?php       
    require_once 'MyAPI.class.php';

    try {
        $API = new MyAPI($_REQUEST, $_SERVER['HTTP_ORIGIN']);
        echo $API->processAPI();
    } catch (Exception $e) {
        echo json_encode(Array('error' => $e->getMessage()));
    }
 ?>

Now another thing. I needed to add responseType:'json' to the ajax request as follows:

var data = {"username":"sarahexample","password":"5f4dcc3b5aa765d61d8327deb882cf99"};
    $http({
        method: 'POST',
        url: 'http://localhost/API/auth',
        data : JSON.stringify(data),
        headers: {
           'Content-Type': 'application/json;charset=utf-8'
        },
        responseType:'json'
    }).then(function successCallback(response) {
        console.log('success');
        if(response.data.hasOwnProperty('error')){
            console.log(response.data.error);

        }else{
            console.log(response.data.username);
        }   
    }, function errorCallback(response) {
        console.log("error");
        console.log(response);

    });
Sarah
  • 1,943
  • 2
  • 24
  • 39
-1

Right way to do this is check your JSON output before echo.

// Check if your JSON conversion succeed

$json = json_encode($_POST);
if ($json === false) {
    // JSONify the error message:
    $json = json_encode(array("jsonError", json_last_error_msg()));
    if ($json === false) {
        // This should not happen, but we go all the way now:
        $json = '{"jsonError": "unknown"}';
    }
    // Set HTTP response status code to: 500 - Internal Server Error
    http_response_code(500);
}
echo $json;
Vipul
  • 1
  • 2