服务器抛出异常,客户端误解为成功


Server throws exception, client misinterprets as success

我正在使用JQuery、PHP和PostgreSQL编写一个简单的登录/注册功能。以下代码来自一个处理登录的PHP文件。当登录名/密码组合错误时,它会引发异常。

$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
$numResults = pg_num_rows($result);
if ($numResults == 0) {
  throw new Exception("Incorrect combination of username and password.");
  //die('Incorrect combination of username and password.');
}

但是,在Jquery文件的客户端上,即使服务器抛出异常,也会执行成功函数。

      $.ajax({
        type: "POST",
        url:"login.php",
        data: dataString,
        success: function() {
//THIS FUNCTION IS EXECUTED....
          $('#errorMsg').html('Login is successful!');
          $('#errorMsg').show();
          $('#usernameTxtBx').val("");
          $('#passwordTxtBx').val("");
        },
        error:function (xhr, ajaxOptions, thrownError){
          window.alert(xhr.status);
          window.alert(thrownError);
        }
      });

首先:请查看SQL注入,因为您很容易受到攻击…;)

问题是,当抛出PHP异常时,HTTP响应代码没有被设置为被解释为错误的代码。你可以这样做来解决这个问题:

function exception_handler($exception) {
    header("HTTP/1.1 400 Bad Request");
    echo "Uncaught exception: " , $exception->getMessage(), "'n";
}
set_exception_handler('exception_handler');

这将把异常处理程序设置为您自己的函数,该函数在退出之前设置正确的HTTP头。通过这种方式,jQuery现在将知道发生了错误,并调用错误处理程序而不是成功。

我选择400 Bad Request作为状态代码,因为这种情况下的错误似乎是由错误输入引起的。我建议将您自己的异常子类化,以检查它是否真的是与客户端相关的异常,如果不是,则发送一个通用的500内部服务器错误。

错误处理程序看起来像这样(如果您将子类命名为UserErrorException):

function exception_handler($exception) {
    if($exception instanceof UserErrorException) {
        header("HTTP/1.1 400 Bad Request");
    } else {
        header("HTTP/1.1 500 Internal Server Error");
    }
    echo "Uncaught exception: " , $exception->getMessage(), "'n";
}
set_exception_handler('exception_handler');

PHP异常不可被Javascript捕获捕获。这些语言在完全不同的时间执行。JS只会看到你的异常MESSAGE出现在电线上。除非您的PHP端异常采取措施发送"200 OK"以外的HTTP状态代码,否则JS将把传入的文本和200 OK代码解释为AJAX请求成功完成。

如果您想让JQuery知道有错误,您必须在PHP脚本的响应中设置正确的头。

标头错误代码列表可在此处找到:http://www.jqueryphp.com/http-header-codes/2011/01/