Search code examples
javascripthttpserverxmlhttprequest

http custom progress feedback to client


I have an http server which, on client request, runs a certain task in the background which may take a bit of time before it returns the results to the client.

Is there a way to update the client with progress information on that specific background task?

There's the progress handler of XMLHttpRequest, but if I understand correctly it's only used for data transfer progress.

In my application, an example of a flow is this:

  1. client sends GET request.
  2. server does things which may take time. How to update client of the progress of things?
  3. server returns a response to the client. Depending on data size, may also take time. XMLHttpRequest progress event can be used here.

Is this part of the http spec? Or do I need something else (websocket..?)

thanks!


Solution

  • You should consider using server-sent events. Here are some places to learn more about it:

    Server-sent events are natively supported in Chrome, Opera, Firefox, and Safari and there are polyfills you can use to make server-sent events work in Edge/IE as well, and even a jQuery plugin.

    Here’s a very simple example of some client-side code:

    var source = new EventSource("/server-side-app-that-gives-progress-updates")
    source.onmessage = function(e) {
      console.log(e.data);
    }
    

    On the server side, your /server-side-app-that-gives-progress-updates app just sends back plain-text data formatted like this:

    data: some data\n
    data: more data\n\n
    

    It starts streaming that by sending a response with a Content-Type: text/event-stream header. The client code above will see it as a single e.data message with "some data\more data".

    When the server app has an update, it just writes another message of that form to the response.

    If you want to send the updates as a series of JSON messages instead, your server app writes:

    data: {"foo": "bar", "hoge": "moge"}\n\n
    

    And then your client code can do this:

    source.onmessage = function(e) {
      var jsonObject = JSON.parse(e.data);
      console.log(jsonObject.foo);
    }
    

    Of course there’s more to it you can learn about at the places cited above. But that’s it in a nutshell.


    I have an http server which, on client request, runs a certain task in the background which may take a bit of time before it returns the results to the client.

    That is one of the key use cases server-sent events were designed for.

    Is there a way to update the client with progress information on that specific background task?

    Yes, you can do that with server-sent events.

    There's the progress handler of XMLHttpRequest, but if I understand correctly it's only used for data transfer progress.

    Right. XHR can’t get progress info on anything happening on the server prior to the it responding.

    In my application, an example of a flow is this:

    Is this part of the http spec?

    It’s not part of the HTTP spec (though HTTP/2 has somewhat-related features).

    Or do I need something else (websocket..?)

    You don’t need WebSockets for this. WebSockets are great for the case where you need real two-way full-duplex communication among the client and server—for example, a real-time chat app.

    But the use case described in the question is instead one where only one-way communication of updates from the server to the client is needed. And that’s exactly what server-sent events are for.