Ben Davidow
Ben Davidow

Reputation: 1215

Parsing PHP response: Uncaught SyntaxError: Unexpected token <

I'm using AJAX to make a call to a PHP script. The only thing I need to parse from the response is a random ID generated by the script. The problem is that the PHP script throws a number of errors. The errors are actually fine and don't get in the way of the program functionality. The only issue is that when I run

$.parseJSON(response)

I get:

Uncaught SyntaxError: Unexpected token < 

Since the PHP response starts with an error:

<br /> 
<b>Warning</b>:

I'm wondering how to change the PHP or JS such that it can parse out the ID despite the errors.

PHP:

  $returnData = array();
  $returnData['id'] = $pdfID;
  echo json_encode($returnData); 
  ...

JS:

 function returnReport(response) {
    var parsedResponse = $.parseJSON(response);
    console.log(parsedResponse);
    pdfID = parsedResponse['id']; 

I know that the warnings should be resolved, but the warnings are not functionality critical for now and more importantly

1) Even if these warnings are resolved new ones may come up down the line and the JSON should still be properly parsed and

2) In addition to the warnings there are 'notices' that cause the same issue.

Upvotes: 7

Views: 16937

Answers (11)

Ben A. Noone
Ben A. Noone

Reputation: 389

There are several ways this could be solved (any one of which would work):

1. Fix your warnings. :
PHP is saying something for a reason.

2. Turn off error reporting & error display:
At the top of your file place the following

error_reporting(false);
ini_set('display_errors', false);<br/>


3. Use the output buffer:
At the top of your file place

ob_start();

When you have your data array and your ready to echo to browser clear the buffer of all notices warnings etc.

ob_clean();
echo json_encode($returnData);
ob_flush();


4. Set a custom error handler:

set_error_handler("myCustomErrorHandler");

function myCustomErrorHandler($errno, $errstr, $errfile, $errline){
    //handle error via log-to-file etc.
    return true; //Don't execute PHP internal error handler
}


5. Optionally in JavaScript:
Sanitse your response to be a JSON array:

function returnReport(response) {
    response = response.substring(response.indexOf("{") - 1); //pull out all data before the start of the json array
    response = response.substring(0, response.lastIndexOf("}") + 1); //pull out all data after the end of the json array
    var parsedResponse = $.parseJSON(response);
    console.log(parsedResponse);
    pdfID = parsedResponse['id']; 
}

Upvotes: 5

If you want to see the error in JavaScript, you should handle the error on PHP with a "try catch" and the "catch" to do something like "echo json_enconde ($ error);" on this way you can parse from JavaScript.

Example:

try{
    $returnData = array();
    $returnData['id'] = $pdfID;
    echo json_encode($returnData);
}catch (Exception $e) {
    echo json_encode($e);
}

I hope this helps :)!

Upvotes: 0

Sanjeevshrestha
Sanjeevshrestha

Reputation: 49

You can use Try..Catch construct in the javascript function code as shown below.

function returnReport(response) {
    try
    {
        var parsedResponse = $.parseJSON(response);
        console.log(parsedResponse);
        pdfID = parsedResponse['id'];
    }
    catch(err)
    {
       //Do something with the err
    }
}

This will work even if your php code generates debug info in response.

Upvotes: 0

Elias Soares
Elias Soares

Reputation: 10264

1st alternative:

Solve the problem causing the warning. A good PHP system should never show a PHP Notice, Warning or Error. This may expose some critical information.

2nd alternative:

Just disable error reporting by setting

error_reporting(0);

This will work, but will hide even to you any errors.

3rd alternative:

Set a error handler function that treat the error and show a JSON friendly error message that does not cause any trouble.

Also I recommend you to log this exceptions. It will allow you to debug any system trouble.

My recomendation?

Use 1st and 3rd alternatives together, and be HAPPY!

Upvotes: 0

Script used in Ajax call just must have perfect constrution, shall not thrown any warnings just by convenience, for production you should have erros disabled, so fix it into development, edit the question with the warning that's phps givin to we help you with directly on the point.

Upvotes: 0

Deepak Goswami
Deepak Goswami

Reputation: 2030

I am sure that there would be some mistakes in your PHP code due to that error is coming please check few things:

  • Make sure that there should not be more than one echo or print in your php code for printing response.
  • jQuery must be included properly.
  • And check the other php code in your function/page that should not produce any run time errors/warnings because it will also create same problem.

I am saying this because I have tried your code and it working fine for me you can check that also:

PHP File: myContentPage.php

<?php 
    $returnData = array();
    $returnData['id'] = 123;
    echo json_encode($returnData); 
?>

HTML File:

<!DOCTYPE html>
<html>
    <head>
        <script type='text/javascript' src='js/jquery.js'></script>
    </head>
    <body>
        <h1>Demo Example</h1>
        <script>
            function loadResponse() {
                var dataString={};
                $.ajax({                                      
                    url:"myContentPage.php",
                    type: 'POST',
                    cache:false,
                    data: dataString,
                    beforeSend: function() {},
                    timeout:10000000,
                    error: function() { },     
                    success: function(response) {
                       var parsedResponse = $.parseJSON(response);
                        pdfID = parsedResponse['id']; 
                        console.log(pdfID);
                        alert(pdfID);
                    } 
                });
            }
            loadResponse();
        </script>
    </body>
</html>

And for handling the warnings you can do these this:

  • To skip warning messages, you could use something like:

    error_reporting(E_ERROR | E_PARSE);

  • or simply add the @ sign before the each line of php code on that you think warning can come

Happy Coding!!

Upvotes: 0

Jan Sverre
Jan Sverre

Reputation: 4723

If ob is enabled

ob_end_clean();
ob_start();

echo json_encode($returnData);

Or, in top of your file

error_reporting(0);

Upvotes: 0

AJReading
AJReading

Reputation: 1223

I know everybody has recommended you fix the errors, I would agree, but if you do not want to then there is another a solution.

If you are getting a number of warnings and expect new warnings could appear, simply disable reporting of warnings and notices:

error_reporting(E_ALL ^ (E_NOTICE | E_WARNING));

Upvotes: 0

Gustavo Rubio
Gustavo Rubio

Reputation: 10807

Like everybody else has said, you SHOULD really fix your errors and handle them accordingly.

This is something more to have under circumstances that you will not control and yet want to handle errors accordingly:

<?php  

//Change it to 'production' or something like that
//so that you don't send debug data on production
define('ENVIRONMENT', 'testing');

//Set your error handler globally
set_error_handler('handle_error');

function handle_error($errno, $errstr, $errfile, $errline, array $errcontext ) 
{
    //Set your headers to send a different than 200 so you can
    //catch it on error on jQuery
    header($_SERVER["SERVER_PROTOCOL"].' 500 Internal Server Error');

    //Set output as json
    header('Content-Type: application/json');

    //Create some sort of response object
    $response = new stdClass;
    $response->message = "Application error details";

    //You dont want to give debug details unless you are not on prod
    if(ENVIRONMENT == 'testing') {
        $severity = get_err_severity($errno);
        $response->error_detail = "({$severity}) [{$errfile}@L{$errline}]: {$errstr}";
        $response->context_vars = $errcontext;
    }

    //Return the json encoded error detail and exit script
    $json = json_encode($response);
    exit($json);
}

function get_err_severity($severity) 
{
    switch($severity) {
        case E_ERROR:
            return 'E_ERROR';
        case E_WARNING:
            return 'E_WARNING';
        case E_PARSE:
            return 'E_PARSE';                   
        case E_NOTICE:
            return 'E_NOTICE';
        case E_CORE_ERROR:   
            return 'E_CORE_ERROR';       
        case E_CORE_WARNING:
            return 'E_CORE_WARNING';               
        case E_COMPILE_ERROR:       
            return 'E_COMPILE_ERROR';                       
        case E_COMPILE_WARNING:     
            return 'E_COMPILE_WARNING';                               
        case E_USER_ERROR:          
            return 'E_USER_ERROR';                               
        case E_USER_WARNING:        
            return 'E_USER_WARNING';                               
        case E_USER_NOTICE:         
            return 'E_USER_NOTICE';                               
        case E_STRICT:              
            return 'E_STRICT';                               
        case E_RECOVERABLE_ERROR:   
            return 'E_RECOVERABLE_ERROR';                               
        case E_DEPRECATED:          
            return 'E_DEPRECATED';                               
        case E_USER_DEPRECATED:                 
            return 'E_USER_DEPRECATED';                               
    }
}


function test_error() 
{
    $test = array('foo'=>'bar');
    $baz = $test['baz'];
    echo $baz;
}

test_error();

Upvotes: 1

Ben Davidow
Ben Davidow

Reputation: 1215

While this doesn't solve the broader issue of warnings, I used this hack to parse the response:

function returnReport(response) {
    var pdfID = parseID(response);
    ...
}

function parseID(response) {
    var responseIndex = response.indexOf('{"id');
    var start = responseIndex + 7;
    var pdfID = response.slice(start, start + 6);
    return pdfID;
}

Upvotes: 0

Kris Oye
Kris Oye

Reputation: 181

Why not deal with and eliminate the warning so that the result from the server is actually JSON?

Upvotes: 14

Related Questions