I'm using the openweathermap API to get a JSON object using the fetch API on my browser which is running on localhost. I can get it to work by avoiding a CORS preflight by using a simple request (i.e. a GET request using content-type:text/plain). If I want anything else (e.g. application/json) then it does a preflight and this is where it fails.
The response I get is "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource" because "CORS preflight response did not succeed (response 405)".
I've checked the response header from api.openweathermap.org and this is what I get from the preflight request:
HTTP/1.1 405 Method Not Allowed
Server: openresty
Date: Wed, 24 Aug 2022 10:47:29 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 40
Connection: keep-alive
X-Cache-Key: /data/2.5/weather?APPID=hidden_key&q=london,uk
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST
The response contains Access-Control-Allow-Origin: * and the allowed method (GET) is listed so I'm assuming cross-site requests are accepted. Am I missing something? The obvious workaround is to use JSON.parse() but for my own learning I'd like to understand why this doesn't work. A snippet of my code is below:
const url='https://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=hidden_key_obvs';
const response=await fetch(url, {method: 'get', mode: 'cors', headers: {'Content-Type': 'application/json'}
});
Many thanks in advance!
CodePudding user response:
The Content-Type
request header tells the server what sort of data you are POSTing or PUTting in the request body.
You are making a GET request.
You don't have a request body.
You can't have a request body.
Your Content-Type
request header is a lie.
The server you are trying to access doesn't accept the OPTIONS request because nothing it offers requires a preflighted request.
You might be confusing Content-Type
with Accept
, which tells the server what sort of data types you can handle in its response.
I suspect the API won't pay attention to that and will always return JSON (with a Content-Type: application/json
response header) regardless.
There is no need to use JSON.parse
since the response object has a json method that will both extract the data from the response body and parse it from JSON in one go.