PUT on a REST API
- Input
- PUT /items/1, Content-Type: application/json
- Expected output
- OPTIONS enviado antes, checando Allow-Methods
The server must answer the preflight, not just the PUT.
OPTIONS preflight for PUT and JSON
A simple PUT to update a resource, the most common pattern in any REST API, falls outside CORS's "simple request" list and forces the browser to send a verification OPTIONS first.
The server must answer the preflight, not just the PUT.
GET with no extra headers is always "simple".
That's exactly the symptom of a CORS block: the browser rejects the fetch() promise before handing any data to JavaScript, without detailing why. The catch is that this same generic message also shows up for DNS, TLS or connectivity failures, so the browser does not distinguish the two for the script that made the call.
Because the GET is likely a "simple" request (no preflight), while the PUT triggers an OPTIONS the server may not be handling correctly, responding with Access-Control-Allow-Methods that doesn't include PUT, for example.
Technically yes, text/plain is on the "simple" type list, but that just moves the problem: the server would have to blindly trust the body is valid JSON without the preflight check, which most APIs avoid for security reasons.
Not necessarily. The browser can cache the preflight result for the time set in Access-Control-Max-Age, avoiding repeating the OPTIONS on every call within that window.
Your browser makes the real request to the URL you enter, exactly like any page would. If the call completes, the current origin was authorized. If it's blocked, the browser never shows the page any data, that alone is the result.
This combination of method and/or headers falls outside CORS's "simple request" list, so before sending the real request, the browser automatically sends an OPTIONS asking the server whether it's allowed. See below what that preflight would look like.
OPTIONS /items/1 Access-Control-Request-Method: PUT Origin: https://jkit.tools
The test request leaves your browser directly for the URL you entered, the J-Kit server never sees, resolves or intermediates that address. It's the same kind of call any script on your own page would make.