cse312.com and your API is at api.cse312.com (Different origins!)Access-Control-Allow-* headersOPTIONS /api/posts/42 HTTP/1.1
Host: api.cse312.com
Origin: https://cse312.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-typeOrigin - The origin of the page that wants to send the requestAccess-Control-Request-Method - The method of the real requestAccess-Control-Request-Headers - The non-safelisted headers the real request will include
Content-Type is listed here since application/json is not one of the 3 simple typesHTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://cse312.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 600Access-Control-Allow-Origin must match the requesting origin (or * to allow all origins)Access-Control-Max-Age - The browser can cache this approval for 600 secondsAccess-Control-Allow-Origin
Access-Control-Allow-Origin: https://cse312.com
https://cse312.com may read this responseAccess-Control-Allow-Origin: cse312.com does not workAccess-Control-Allow-Origin: *
state parameter<form action="https://bank.com/api/transfer" method="post" enctype="text/plain">
<input type="hidden" name='{"to": "attacker", "amount": 10000, "x": "' value='"}'>
</form>text/plain form sends name=value with no encoding{"to": "attacker", "amount": 10000, "x": "="}Content-Type: application/json
fetchHttpOnly, so JavaScript can read it)