简体   繁体   中英

How to correctly assign Headers to fetch request in Javascript

I'm quite new to more advanced APIs, and I'm trying to send a GET request to an external API using fetch, with the appropriate Headers as detailed by the API owner.

However, I'm still receiving a 403 Forbidden error, and it seems that the headers are not actually being sent with the request as the Chrome DevTools shows "Provisional headers are being shown".

I'm using a CORS proxy: https://cors-anywhere.herokuapp.com/ , which has worked with other simpler API requests.

const proxy = 'https://cors-anywhere.herokuapp.com/';
const api = `${proxy}https://api-example.com`; // Obfuscated


// Generate the data
fetch(api, data = {}, {
    credentials: "include",
    method: "GET",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      Authorization: "Bearer eLrw3eXlljyFRjaul5UoYZLNgpUeapbXSFKmLc5SVaBgv8azUtoKn7B062PjbYoS",
      "User-Agent": "any-name"
    },
    body: JSON.stringify(data)
})
    .then(response => {
        return response.text();
    })

The API request works in Postman and using curl, but with my application I receive a 403 Forbidden response. As also mentioned, only provisional headers are shown in the request headers; none of the headers I had set.

Any help would be much appreciated. Thanks!

It looks as though you are passing an empty object as the options. The fetch() function only takes two parameters, the resource (uri) and an object of options (see: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch ). You have an empty object data = {} as the second parameter and your options specified as an unused, third parameter. I believe what you want is to remove the data parameter, especially since you don't need to send a body in a GET request.

fetch(api, {
    credentials: "include",
    method: "GET",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      Authorization: "Bearer eLrw3eXlljyFRjaul5UoYZLNgpUeapbXSFKmLc5SVaBgv8azUtoKn7B062PjbYoS",
      "User-Agent": "any-name"
    }
})
.then(response => {
    return response.text();
})

The api works in Postman and curl and if you are sure you are sending all request and headers same way then it probably is CORS issue. You have not provided enough information to truly understand if that is the case.

However I am trying to explain what I understand how CORS work for browsers. Browsers before making a request (eg GET, POST, DELETE etc) makes an OPTIONS request. If the server that handles the request sees that the request is allowed for that host (using the origin and a few other factors), the server responds with a successful response. When browsers see that the OPTIONS request is successful then the browser executes the actual request (GET, POST, DELETE, whatever).

Sometimes for local development you may need to overcome this as localhost will not be supported by the server. In this case you can use browser extensions that intercepts your xhr requests and mocks a successful OPTIONS request for your browser and your browser thinks server responded with successful for OPTIONS call so then it allows the call.

Sending the headers with your request will not work. The api server must allow options request to be returned with status 200 for your app to be able to make that call from browser.

All the above is based on that you sent the request from your browser the same way as from postman or curl. You can verify that if you use a network monitor app like Fiddler if you use windows. If you are on macOS or Linux, I am not aware of a tool like Fiddler, there must be tools but as I don't work on those platform, I cannot suggest another tool to monitor network.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM