On Sync, Async, and Cross-Origin
A recent project combined two concepts—async calls and cross-origin navigation—so I jotted down the reasoning.
Scenario
Site A must post data to site B and then land on a page served by B. The integration team on B’s side told us the endpoint returns a full HTML document whose JavaScript performs the redirect. We have to consume that response as-is.
Options considered
Async request?
An async XHR/Fetch call would immediately run into CORS, which we could solve, but we’d then receive a blob of HTML. We’d have to open a window, inject that HTML, and let it execute. The response references third-party scripts, so parsing and running it ourselves is error-prone. Not ideal.
Chosen approach
We submit a hidden form from site A to site B. B responds with the full HTML document, and the browser renders it natively. No manual parsing, no extra work.
Why this works
A simple problem, but it highlights a few browser rules worth remembering.
Form submissions and cross-origin
Under the same-origin policy, XHR/Fetch requests can’t read cross-origin responses without explicit permission—otherwise site A could steal data from site B. Traditional form submissions are different: the browser sends the request and replaces the current document with the response. Site A never gets access to B’s data, so the browser treats it as safe. (See Same-origin policy.)
Sync vs. async
A form submit is synchronous: the current page halts while the request completes and the new page loads. Async requests, by contrast, let the page keep executing while the request runs in the background. (See AJAX and this explainer on async vs. multithreading vs. parallelism.)
Browser parsing
Because the browser treats the response as a full navigation, it parses and renders the returned HTML—including any scripts that redirect to the final destination.
Final Thoughts
Sometimes the simplest tool—a synchronous form submit—is the right answer. Front-end work is filled with small, nuanced rules; keep exploring and practicing.