使用AJAX XMLHttpRequest时,Symfony StreamedResponse的响应文本会连接在一起

时间:2017-04-28 16:13:22

标签: javascript ajax symfony xmlhttprequest

我有一个控制器,一旦调用端点,它就会返回Line 1(作为响应)。两秒钟后它返回Line 2。当我直接访问URL http://ajax.dev/app_dev.php/v2时,这很好,所以这证明端点按预期工作。

/**
 * @Method({"GET"})
 * @Route("/v2", name="default_v2")
 *
 * @return Response
 */
public function v2Action()
{
    $response = new StreamedResponse();
    $response->setCallback(function () {
        echo 'Line 1';
        ob_flush();
        flush();

        sleep(2);
        echo 'Line 2';
        ob_flush();
        flush();
    });

    return $response;
}

当我使用AJAX调用同一个端点时,第一个响应很好,即response: "Line 1"。但是,第二个是response: "Line 1Line2",因此它被合并。我应该怎么做才能将response: "Line2"作为第二个回复?请参阅下面的控制台日志。

XMLHttpRequest { onreadystatechange: xhr.onreadystatechange(), readyState: 3,
timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload,
responseURL: "http://ajax.dev/app_dev.php/v2", status: 200, 
statusText: "OK", responseType: "", response: "Line 1" }

XMLHttpRequest { onreadystatechange: xhr.onreadystatechange(), readyState: 3,
timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload,
responseURL: "http://ajax.dev/app_dev.php/v2", status: 200, 
statusText: "OK", responseType: "", response: "Line 1Line2" }

Complete

这是我正在使用的AJAX。

$(document).ready(function () {
    $('button').click(function () {
        xhr = new XMLHttpRequest();
        xhr.open("GET", 'http://ajax.dev/app_dev.php/v2', true);
        xhr.onprogress = function(e) {
            console.log(e.currentTarget);
        };
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                console.log("Complete");
            }
        };
        xhr.send();
    });
});

1 个答案:

答案 0 :(得分:0)

现在这只能是暂时的解决方案,因为每一个响应都会加起来并成为一个大规模的响应,而不是一个干净的响应。

e.g。

Response 1: Hello
Response 2: World
Response 3: Bye

XMLHttpRequest e.currentTarget属性包含:

Hello
HelloWorld
HelloWorldBye
  

The responseText property of XMLHttpRequest always contains the content that's been flushed out of the server, even when the connection's still open. So the browser can run a periodic check, e.g. to see if its length has changed.

暂时我会使用下面的代码,但如果我能找到更好的解决方案,我会发布它。

<script>
    $(document).ready(function () {
        $('button').click(function () {
            xhr = new XMLHttpRequest();
            xhr.open('GET', 'http://ajax.dev/app_dev.php/v2', true);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

            xhr.onprogress = function(e) {
                var response = e.currentTarget.response;
                var output = typeof lastResponseLength === typeof undefined
                    ? response
                    : response.substring(lastResponseLength);

                lastResponseLength = response.length;
                console.log(output);
            };

            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    console.log('Complete');
                }
            };

            xhr.send();
        });
    });
</script>