Let's get into the problem
Using Netlify as a hosting service where it proxy requests coming from web client to backend server, while the backend server was still streaming data the stream was dropped unexpectedly. The streaming failure was intermittent and a red herring to the actual problem, and disguised itself in different forms on different browsers:
- On Firefox, logs a stream deserialization error
error decoding response body
- On Chrome,
stream ended before completing
There is a clue in Netlify documentation:
Proxy rewrite requests will time out after 26 seconds. If you are proxying to a longer-running process, we recommend making an asynchronous request rather than waiting for a response.
Netlify rewrites are used to map a URL in the visitor's address bar to a different resource on the server, without changing the displayed URL. This is useful for single-page applications (SPAs), proxying requests to other services, or transitioning legacy content while keeping the original URL visible.
Within a Netlify toml file in your UI project, you can put in a redirect
directive to reroute the calls to API endpoints, so that no extra CORS headers need to be added on server side. However, this was causing more headaches than it solves, stream was dropped after 10-20 seconds intermittently. To regain the some control back to allow the streamed data to come through, we actually cannot reply on Netlify proxy and will need to write CORS headers in the server responses.
Note that there is another layer of complication on top of Netlify proxy timeout, Chrome and Firefox will log errors ERR_INCOMPLETE_CHUNKED_ENCODING
and NS_ERROR_NET_PARTIAL_TRANSFER
if no data has been sent for over 60 seconds, so be wary of multiple big requests coming into the server at the same time.
What is CORS?
To understand what is CORS, perhaps the first question we should be asking is what came before CORS? The was the same-origin policy, the primary mechanism for restricting web page access to resources from different origins. This policy was designed to enhance security by preventing malicious websites from accessing sensitive data on other domains. It meant that a webpage loaded from http://example.com
could only access resources on http://example.com
and not, for example, http://anothersite.com
.
CORS (Cross-Origin Resource Sharing) was introduced as a mechanism to relax the same-origin policy in a controlled way, allowing web applications to access resources from different origins under specific conditions. Therefore if your service is not accessed from the same domain as the browser page, without a proxy, in order to make requests directly to the API backend you will need to specify in the server:
- allowed methods
Access-Control-Request-Method
: GET, POST, PUT DELETE, OPTIONS (the intended method of the request) - allow headers
Access-Control-Request-Headers
, if you are using custom headers - allowed origin
Access-Control-Allow-Origin
, set as environment variable for example with the base URL of expected client. You may want to allow any origin for development.
Only the allowed origin is compulsory for Simple requests (GET, POST, and HEAD), otherwise browser makes an automatic pre-flight request using the OPTIONS
method to determine the full CORS capabilities of the server before the actual request is executed.
CORS is flawed..
CORS (Cross-Origin Resource Sharing) is a security feature implemented by browsers to prevent malicious websites from making unauthorized requests to your backend services (like APIs) on behalf of a logged-in user. It’s a necessary part of web security, but it has some issues. CORS is a helpful layer, but it’s not a complete security solution. Think of it as a gatekeeper for browsers — useful, but easily bypassed if your server isn’t properly secured.
Only enforced by browsers
CORS is a client-side mechanism — it protects users in a browser. If someone uses tools like curl, Postman, or scripts outside a browser, they can bypass CORS completely.
Easy to misconfigure
Many developers unintentionally open up their APIs by setting Access-Control-Allow-Origin: * or enabling too many headers/methods, which can expose sensitive data.
Annoying complexity
CORS introduces preflight OPTIONS requests, credential flags, and other configurations that often confuse developers. It’s easy to break things or introduce bugs if you're not careful.
Not real protection for your backend
Since it only works in browsers, CORS doesn’t protect your server by itself. You still need authentication, authorization, rate limiting, etc., on the backend to stay secure.
Top comments (0)