'Why does having a ReadableStream body trigger a CORS preflight request?

The logic in the fetch spec behind whether a browser request needs a preflight is based on whether it is "simple". For example, setting custom headers is not simple and requires a preflight. My understanding is that this is mostly about ensuring that the request is likely to be "getting a resource" and not "executing an API".

One of the conditions is that the body is not a ReadableStream. Why does that matter? From a security perspective, I can imagine "anything with a body at all should be preflighted" making sense, but that's not the logic: it's "strings are OK, ReadableStreams are not".



Solution 1:[1]

The issue at hand, as @sideshowbarker alludes to in his comment, is whether the server is equipped to handle Transfer-Encoding: chunked, which is automatically sent for ReadableStream bodies. (Since we don't know their length ahead of time.)

Before ReadableStream fetches, it was not possible to send a cross-origin Transfer-Encoding: chunked request. E.g., there's no way to do that with <form>. So this represents a new thing that browsers could do to unsuspecting servers, including to intranet servers. Thus, the preflight: the server has to say "yes, I am OK with getting requests from that origin, and am prepared for the consequences".

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Domenic