XMLHTTPRequest 可以捕获表单数据,并发送到要发布的 PHP cURL 请求吗?

问题描述

我有一个 javascript 文件,用于捕获表单输入、使用输入发出 XMLHTTP POST 请求并处理错误。我目前正在发布到一个单独的 PHP 文件,因为该请求需要敏感的 API 数据并需要编码。然后,我从 PHP 文件发送一个 cURL 请求,将表单输入发布到远程 URL。

我想根据 cURL 响应处理错误,但 XHR 错误是不同的,并且优先于 cURL 错误。这两个请求都是必需的,还是我应该只发出一个 XHR 或 cURL 请求?

解决方法

是否需要两个请求取决于您的用例。既然你的听起来确实是必要的,那绝对没有错。

您如何处理服务器端错误客户端也完全取决于您。例如,让我们假设这个非常基本的 XHR 处理程序,它将一些 JSON 数据发送到某个端点并评估响应:

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

上述错误处理策略围绕着从服务器接收到的 HTTP 状态代码,因此我们需要确保它们是根据我们的需要发送的:

/**
 * 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

关于cURL,您可以轻松地将最后两行更改为例如:

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

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

    success($data);
}

或者您调整错误函数 - 如果它接受一个数组而不是一个简单的字符串,您将能够向您的 JavaScript 客户端返回更复杂的错误数据:

$curl_error = curl_errno($ch);

if ($curl_error) {

    error([

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

不过,您不必坚持使用状态代码来处理错误。您可以发回一个 JSON 对象,其中一个键表示一些成功收集的数据,一个键表示发生错误时的错误。或者任何适合您的需求。