Skip to content
Advertisement

Can an XMLHTTPRequest capture form data, and be sent to a PHP cURL request to be posted?

I have a javascript file that captures form input, makes an XMLHTTP POST request with the input, and handles errors. I am currently POSTing to a separate PHP file, as the request requires sensitive API data and needs encoding. From the PHP file, I then send a cURL request to post the form input to the remote URL.

I want to handle errors based on the cURL response, but the XHR errors are different and take precedent over the cURL errors. Are both these requests necessary, or should I only be making either a single XHR or cURL request?

Advertisement

Answer

Whether or not both requests are necessary depends on your use case. Since yours sounds as they are indeed necessary, there’s absolutely nothing wrong with it.

How you handle server-side errors client-side is also entirely up to you. For example, let’s assume this pretty basic XHR handler, which sends some JSON data off to some endpoint and evaluates the response:

var xhr = new XMLHttpRequest();

xhr.open('POST', '/endpoint.php');
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onload = () => {

    const status   = xhr.status;
    const response = JSON.parse(xhr.responseText);
    
    if (status == 200) {

        // Everything's fine
        console.log(response.data);

    } else {

        // Some error occured
        console.log(status, response.data);
    }
};

xhr.send(JSON.stringify({}));

index.html

The above error handling strategy revolves around the HTTP status code received from the server, so we’ll need to make sure they’re send according to our needs:

/**
 * In case an error occurred, send an error response.
 */ 
function error(string $message) {

    // For properly returning a JSON response, see:
    // https://stackoverflow.com/a/62834046/3323348
    header("Content-type: application/json; charset=utf-8");
    http_response_code(400); // HTTP status code - set to whatever code's appropriate

    echo json_encode(['data' => $message]);
}

/**
 * Send a response denoting a success.
 */ 
function success(array $data) {

    // For properly returning a JSON response, see:
    // https://stackoverflow.com/a/62834046/3323348
    header("Content-type: application/json; charset=utf-8");
    http_response_code(200);

    echo json_encode(['data' => $data]);
}

// For proper error checking on JSON data, see:
// https://stackoverflow.com/a/37847337/3323348
$data = json_decode(file_get_contents('php://input'), true);

// Assume some processing happened. That result is either
// a success, or an error.
$success = mt_rand(0,1);
$success ? success($data) : error('An error occured.');

endpoint.php

Regarding cURL, you could easily change the last two lines to e.g.:

if(curl_errno($ch)) { // Assuming $ch is your cURL handle

    error('Curl error: '.curl_error($ch));
}
else {

    success($data);
}

Or you adapt the error function – if it would accept an array instead of a simple string, you’d be able to return more complex error data to your JavaScript client:

$curl_error = curl_errno($ch);

if ($curl_error) {

    error([

        'type' => 'cURL', 
        'no' => curl_errno($ch), 
        'message' => curl_error($ch)
    ]);
}

You don’t have to stick with status codes for your error handling, though. You could send a JSON object back with one key denoting some successfully collected data, and one denoting an error if an error occurred. Or whatever suits your needs.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement