AJAX 中的空 PHP 响应对象,但仅在成功时

Empty PHP response object in AJAX but only on success

为了从我的 PHP 服务器接收我的响应对象,我在下面提供了代码。 首先,它有效。不起作用的是,如果满足我的第一个 PHP 条件,我的 Ajax 中的成功函数会正确响应,但只是不使用 data 对象。

这是我的 AJAX 函数:

$.ajax({
    type: "PUT",
    url: "http://server/register",
    contentType: "application/json", 
    data: '{"username":"' + username + '", "password":"' + password + '"}',
    success: function(data) {             
        console.log(data)  // The output in my dev tools under Firefox is just a blank line, no error message or even "undefined".           
        console.log("Success") // Works!
        if(data.status == 200){ 
            console.log("Test 1") // Doesn't work. Although status code 200 is shown to me.
        }                       
    },
    error: function(data) {
        console.log(data)   // This works! I can see the content of the object. The correct status code (409) is shown to me.
        if(data.status == 409){
            console.log("Test 2") // Works
        }            
    }
}); 

这是我的 PHP 函数:

public function register($request, $response)
{              
    ...

    if(condition-1) {
        echo("Condition 1 works!"); // Works.
        return $response->withStatus(200);                    
    } elseif(condition-2) {
        echo("Condition 2 works!"); // Works too.
        return $response->withStatus(409);            
    }      
}         

我不明白为什么没有 data 对象。我正在使用 Slim 3 Framework 并且可能 return 一个 JSON 像这样的对象:

$content = ["foo" => 'bar', ...] ; //Any data you wish to return
return $response->withJson($content);

但到目前为止,我的整个代码都可以在不使用 JSON 对象的情况下运行。即使我 var_dump $response 对象,我也可以在服务器端看到它就在那里。

if(condition-1) {
    var_dump($response->withStatus(200)); // Works. I can see it.                
}

尝试使用以下return:

$content = ["foo" => 'bar', ...] ; //Any data you wish to return
return $response->withStatus(200)->withJson($content);

这里有很多错误,所以我已尽力指出我看到的错误,希望通过我建议的更改您会成功。

如果您尝试在 ajax 成功函数中使用 data.status,那么看起来您认为自己正在返回 json,但实际上并没有。即使你是,你也在通过回显 "Condition 1 works!".

来破坏它

所以想一想,如果您有这样的 json 回复:

{'a':'1'}

你在它之前回显了一些东西,你的回应被破坏了,看起来像这样:

Condition 1 works!{'a':'1'}

如果 PHP 以您的方式抛出错误,则会发生同样的损坏,因此请注意这一点。

您还应该为 ajax 请求声明数据类型,因此:

$.ajax({
    type: "PUT",
    url: "http://server/register",
    contentType: "application/json", 
    data: JSON.stringify({
        "username": username, 
        "password": password
    }),
    dataType: 'json', // <-- THIS LINE IS IMPORTANT
    success: function(data, textStatus, jqXHR) {
        // ...
    },
    error: function(jqXHR, textStatus, errorThrown) {
        // ...
    }
});

注意:您是单引号数据 object,所以您这样做很困难。就像我一样在 JS object 上使用 JSON.stringify!

由于我的代码需要 json 响应,因此请务必查看此处的其他答案,因为它展示了如何使用 slim 发回正确的 json 响应。

最后,在您的 ajax 成功函数中,data.status 将永远不可用。 jQuery 的文档显示有三个参数,(data, textStatus, jqXHR) 和数据专门用于数据,而不是 HTTP 状态代码或任何 headers.

我整理了一个迷你 Slim 应用程序的完整示例。它已经过全面测试并且可以正常工作(只是不够好,所以不要笑):

<?php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require 'vendor/autoload.php';

$app = new \Slim\App;

$app->get('/', function (Request $request, Response $response) {
    $response->getBody()->write('<!doctype html>
    <html>
        <head>
            <script
              src="https://code.jquery.com/jquery-3.2.1.min.js"
              integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
              crossorigin="anonymous"></script>
            <script>
                $(document).ready(function(){
                    $("p").on("click", function(){
                        var username = "kookoopapa";
                        var password = "gr3atp4ssWerd";
                        $.ajax({
                            type: "PUT",
                            url: "/register", 
                            data: JSON.stringify({
                                "username": username, 
                                "password": password
                            }),
                            contentType: "application/json", 
                            dataType: "json", // <-- THIS LINE IS IMPORTANT
                            success: function(data, textStatus, jqXHR) {
                                alert( data.a );
                                alert( data.b );
                            },
                            error: function(jqXHR, textStatus, errorThrown) {
                                // ...
                            }
                        });
                    });
                });
            </script>
        </head>
        <body>
            <p>Click</p>
        </body>
    </html>');
    return $response;
});

$app->put('/register', function (Request $request, Response $response) {
    $php_input = file_get_contents('php://input');
    $vars = json_decode( $php_input, TRUE );
    $content = [
        'a' => $vars['username'],
        'b' => $vars['password']
    ];
    return $response->withStatus(200)->withJson($content);
});

$app->run();