vbence
vbence

Reputation: 20333

Using ReadableStream with POST using fetch API

I am trying to do a POST request with the fetch() API. I pass an instance of ReadableStream as request body as suggested on this MDN page.

Instead of posting data from the stream, the ReadableStream object is just converted to string (resulting in the string [object ReadableStream]) and set as request body (see Wireshark frame below).

How correctly connect stream APIs with fetch?

Note: tested in Chrome Version 78.0.3904.87 (Official Build) (64-bit) and Firefox 70.0.1 (64-bit).

Minimal example:

<html>
<head></head>
<body>
    <button id="btn">Button</button>
    <script>
        class StreamBuffer {

            constructor() {
                this.data = new Uint8Array(0);
                this.onChunk = null;
            }

            addBinaryData(uint8Array) {
                const newData = new Uint8Array(this.data.length + uint8Array.length);
                newData.set(this.data, 0);
                newData.set(uint8Array, this.data.length);
                this.data = newData;

                if (typeof this.onChunk === 'function') {
                    this.onChunk(this.data);
                    this.data = new Uint8Array(0);
                }
            }
        }

        class BufferedStream {
            constructor(streamBuffer) {
            const buffer = streamBuffer;

            this.readable = new ReadableStream({
                    start(controller) {
                        buffer.onChunk = chunk => controller.enqueue(chunk);
                        buffer.onClose = () => controller.close();
                    }
                });
            }
        }

        const button = document.querySelector('#btn');
        const buffer = new StreamBuffer();
        const readWriter = new BufferedStream(buffer);
        const readable = readWriter.readable;

        button.onclick = function() {
            var url = 'http://localhost:8080/endpoint';
            fetch(url, {method: "POST", body: readable});
        }

    </script>
</body>
</html>

From Wireshark:

Frame 4: 412 bytes on wire (3296 bits), 412 bytes captured (3296 bits) on interface 0
Null/Loopback
Internet Protocol Version 6, Src: ::1, Dst: ::1
Transmission Control Protocol, Src Port: 55785, Dst Port: 8080, Seq: 1, Ack: 1, Len: 348
Hypertext Transfer Protocol
Line-based text data: text/plain (1 lines)
    [object ReadableStream]

Upvotes: 3

Views: 1576

Answers (1)

Inuart
Inuart

Reputation: 1512

I've found that Chrome is still in the process of implementing this feature. See this issue

Upvotes: 2

Related Questions