"Your frontend is still a browser. The instant it calls fetch, every browser rule you forgot about is back — including CORS."
The Trap: fetch in a Webview Is Browser fetch
It's tempting to forget, but the webview running your UI is a browser, and fetch() from your frontend obeys browser security — including CORS. A specific, maddening corner: JavaScript can only read the response headers a server has explicitly allowed via Access-Control-Expose-Headers. The request succeeds, the body is fine, but response.headers.get("X-My-Custom") returns null — not because the header isn't there, but because the browser hides it from JS unless the server opted in. This cost Cinder a debugging session: a custom header was being sent, the webview just refused to surface it.
Fix 1: Expose the Header (if you control the server)
If the server is yours, add the header name to Access-Control-Expose-Headers. Now the webview's fetch is allowed to read it. This is the correct fix when the API is under your control — it's a normal CORS configuration, exactly as you'd do for any web app hitting a cross-origin API.
Fix 2: Route Through Rust (the escape hatch)
The deeper move: don't make the HTTP call from the webview at all. Make it from Rust — with reqwest or the official tauri-plugin-http — inside a command, and return the data (or the headers you care about) to the frontend. The Rust core is not a browser; CORS does not apply to it. This both sidesteps the header problem and keeps secrets like API keys out of the webview. Whenever frontend networking fights you with CORS, ask whether that request belongs in Rust instead.