This approach was what we had to use back in the late 90s. We called it "iframe streaming", or "forever iframe" (and years later, as an industry term emerged, "comet"). It worked surprisingly well, except in cases where a client sat behind a greedily buffering proxy. We would send JavaScript statements that invoked callbacks on the client, rather than just JSON, as this avoided the need to parse data to determine which business logic to use on the client. This has the limitation of being "non-cross domain" (i.e. the web page containing the callback functions have to be served from the same domain as the infinite document).<p>To get around buffering proxies, we optionally allowed our clients to use a JSONP long polling approach instead, whereby the client would dynamically generate a form inside a hidden iframe, and POST a request for JSONP data (JSON delivered wrapped in a callback), and the server would return data as soon as any was available. The client would immediately repeat the process to request more data, an infinitum.<p>Eventually, the emergence of the XMLHTTPRequest object in IE (and subsequently in other browsers) allowed us to implement cleaner long-poll-style methods, holding the connection open until data was available (and automatically reconnecting on error). This was later enhanced with CORS for delivery of data from arbitrary domains. As support for detecting updates to an in-progress response became available (via XMLHTTPRequest's "progress" event, which for a long time was horribly buggy in IE ) our payloads became infinite streams too (of JavaScript callback invocations). Early versions of approach also required us to reload the entire page from time to time, as IE's underlying implementations of these browser objects appeared to have memory leaks (that we did not see in Firefox, for example).<p>When IE8 was released, we allowed clients to optionally use its XDomainRequest object to stream a response instead.<p>Years later, the much cleaner Server Sent Events (SSE) and WebSocket options became possible. Intermediate proxy support was initially troublesome however, and while both of these were our preferred choices from a performance and API perspective, it took several years before we could consider removing support for our earlier approaches. Even today, there are network environments where an infinite sequence of long polls is the only reliable option...<p>My preference today? The JavaScript fetch API for sending commands, with a simple ack as a response, and an async flow of events over a persistent SSE connection, that feed into a simple JS message bus (implemented using the browser's native event API) for delivery to vanilla JavaScript web components. Simple, clean, and consistent.