3

I have the controller below which returns Line 1 (as response) as soon as the endpoint is called. Two seconds later it returns Line 2. This is fine when I directly access URL http://ajax.dev/app_dev.php/v2 so this proves that the endpoint works as expected.

/**
 * @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;
}

When I use AJAX to call the same endpoint, the first response is fine which is response: "Line 1". However, the second one is response: "Line 1Line2" so it is combined. What should I do in order to get response: "Line2" as the second response? See console log below.

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

This is the AJAX I am using.

$(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();
    });
});
BentCoder
  • 12,257
  • 22
  • 93
  • 165
  • Possible duplicate of [jquery ajax, read the stream incrementally?](http://stackoverflow.com/questions/7740646/jquery-ajax-read-the-stream-incrementally) – yceruto Apr 28 '17 at 21:47
  • 1
    Look at this answer http://stackoverflow.com/a/18964123/4224384 – yceruto Apr 28 '17 at 22:00
  • 1
    @yceruto The link has been helpful! Thank you. So the problem I'm facing is a default behaviour of XMLHttpRequest. [The responseText property of XMLHttpRequest always contains the content that's been flushed out of the server, even when the connection's still open.](https://web.archive.org/web/20111016010552/http://ajaxpatterns.org/HTTP_Streaming). Looks like I'll have to do a length check as well. – BentCoder Apr 28 '17 at 22:33

1 Answers1

0

This can only be a temporary solution for now because every single response adds up and become a massive response rather than having a clean response.

e.g.

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

XMLHttpRequest e.currentTarget property would contain:

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.

For the time being I'll use code below but if I can find a better solution, I'll post it.

<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>
BentCoder
  • 12,257
  • 22
  • 93
  • 165