can't get api responce using fetch() - javascript

I am trying to get data using fetch() using browser console number of time but can't get.
for the cross browser issue I also use mode: no-cors but no solution I found .
please help me out I am fully in depressed now
the code that i already tried:
await fetch("https://api.sandbox.bigbuy.eu/rest/catalog/productsstock.json", {
method: "GET",
mode: 'no-cors',
headers: { Authorization: `Bearer XXXXXXXXXXXX` }
})
.then(response => response.json())
response is:
SyntaxError: Unexpected end of input

You said mode: 'no-cors' but you are making a cross-origin request.
You cannot read data across origins without permission from CORS.
By explicitly turning off CORS you are telling fetch to set the response to nothing and not raise errors for trying to read across origins without permission from CORS.
Change it to mode: 'cors'. Note that api.sandbox.bigbuy.eu will have to grant you permission to read the data.

Related

Enable Cross-Origin Requests (CORS) in POCO C++ Libraries

I'm building a C++ backend with heavy calculations that are meant to work as an JSON API for connecting clients. To accomplish this, I've used HTTPServer in Poco::Net from POCO C++ Libraries.
Unfortunately when building two different clients it turned out that a regular webpage (HTML+JS) can't use Fetch to communicate with the backend due to CORS error. My understanding is that they need to use the same localhost: and that's not the case when manually opening the HTML document on the computer that's also running the backend.
All I can come up with when searching is the generic advice that servers need to enable CORS and whitelist relevant domains. Unfortunately I can't find documentation on how to accomplish this. The only relevant result was an answer on a related question where he recommended the following:
response.set("Access-Control-Allow-Origin", "*");
Naturally whitelisting everything isn't recommended from a security point of view but the main goal here is to just get it running locally to continue the development. Unfortunately it seems to make no difference and the browser console still says:
Access to fetch at 'http://localhost:6363/' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Hovering the error in the Chrome Network tab I get the following:
Cross-Origin Resource Sharing error: PreflightMissingAllowOriginHeader
My current JavaScript call:
const data = { test: 'test' }
fetch('http://localhost:6363', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.text())
.then(message => {
console.log('Data retrieved:', message);
})
.catch((error) => {
console.error('Error:', error);
});
Any suggestions on how to proceed?

Azure get access token via javascript

I'm trying to get an access token from Azure. I was following this tutorial, but the thing is that the guy's using postman. It works for me in postman as well, but it fails in javascript and I don't understand why.
function getAccessToken() {
fetch(`${loginUrl}${tenantId}/oauth2/token`, {
method: "POST",
body: JSON.stringify({
grant_type: "client_credentials",
client_id: clientId,
client_secret: clientSecret,
resource: resource,
})
})
.then((response) => {
console.log(JSON.stringify(response));
})
.catch((err) => {
console.log(JSON.stringify(err));
});
}
The credentials are good, i.e. the clientId, secret, tenantid etc.
I also tried in PowerShell and it worked:
Invoke-RestMethod `
-Uri "$loginUrl$tenantId/oauth2/token" `
-Method Post `
-Body #{"grant_type"="client_credentials"; "resource" = $resource; "client_id" = $clientId; "client_secret" = $clientSecret }
But on js I get the following error:
Access to fetch at 'https://login.microsoftonline.com/myTenantId/oauth2/token' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I'm running this script in an HTML file for testing purposes at the moment.
If we directly call the rest api from a domain different from your website in the HTML page, we will get CORS issue. This is for safety reasons. For more details, please refer to here.
So if you want to get Azure AD token in HTML page, I suggest you use package msaljs to implement implicit flow to get token. The package has fixed cors issue. Regarding how to do that, please refer to here.
Besides, if you still want to use client credentials flow to get token in your HTML page. You have two choices. One choice is to use proxy server. The proxy acts as an intermediary between a client and server. For future details about it, please refer to the blog.

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 (e.g 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.

How do I fix CORS issue in Fetch API

I'm building a front-end only basic Weather App using reactjs. For API requests I'm using Fetch API.
In my app, I'm getting the current location from a simple API I found
and it gives the location as a JSON object. But when I request it through Fetch API, I'm getting this error.
Failed to load http://ip-api.com/json: Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
So I searched through and found multiple solutions to fix this.
Enabling CORS in Chrome solves the error but when I deploy the app on heroku, how can I access it through a mobile device without running into the same CORS issue.
I found an proxy API which enables the CORS requests. But as this is a location request, this gives me the location of the proxy server. So it's not a solution.
I've gone through this Stackoverflow question and added the headers to the header in my http request but it doesn't solve the problem. (Still it gives the same error).
So how can I solve the issue permanently ? What's the best solution I can use to solve the CORS issue for http requests in Fetch API ?
if you are making a post, put or patch request, you have to stringify your data with body: JSON.stringify(data)
fetch(URL,
{
method: "POST",
body: JSON.stringify(data),
mode: 'cors',
headers: {
'Content-Type': 'application/json',
}
}
).then(response => response.json())
.then(data => {
....
})
.catch((err) => {
....
})
});
To the countless future visitors:
If my original answer doesn't help you, you may have been looking for:
Trying to use fetch and pass in mode: no-cors
What is an opaque response, and what purpose does it serve?
Regarding the issue faced by the OP...
That API appears to be permissive, responding with Access-Control-Allow-Origin:*
I haven't figured out what is causing your problem, but I don't think it is simply the fetch API.
This worked fine for me in both Firefox and Chrome...
fetch('http://ip-api.com/json')
.then( response => response.json() )
.then( data => console.log(data) )
You should use the proxy solution, but pass it the IP of the client instead of the proxy. Here is an example URL format for the API you specified, using the IP of WikiMedia:
http://ip-api.com/json/208.80.152.201

Request header field Time-Zone is not allowed by Access-Control-Allow-Headers in preflight response

I have a WEB API which I am consuming from POSTMAN, and it works perfectly fine:
Headers:
Content-Type:application/json
X-Developer-Id:asdasdas
X-Api-Key:asdasdas
Authorization:Bearer sasdasdsa
Time-Zone:Morocco Standard Time
When I do a GET request in POSTMAN it works fine, however from angular 2 (Ionic 2) I get the following error:
Request header field Time-Zone is not allowed by Access-Control-Allow-Headers in preflight response.
let params: URLSearchParams = new URLSearchParams();
params.set('date', date);
//Header
let headers = new Headers({
'Content-Type': AppSettings.ContentType,
'X-Developer-Id': AppSettings.XDeveloperId,
'X-Api-Key': AppSettings.XApiKey,
'Time-Zone': AppSettings.time_zone,
'Authorization': AppSettings.Authorization + localStorage.getItem("AccessToken")
});
var RequestOptions: RequestOptionsArgs = {
url: AppSettings.UrlAvailability + userId,
method: 'GET',
search: params,
headers: headers,
body: null
};
return this.http.get((AppSettings.UrlAvailability + userId), RequestOptions)
.map(res => res.json())
.do(data => { data },
err => console.log('error: ' + err));
First I would think that the API developers have to do something on the server side, like enabling that Time-Zone Header on CORS, however if that would be the case then we would get the same error on POSTMAN, but it works fine there.
What am I missing here?
This is something you need to configure on the server. You first need to make sure you have CORS support. I don't use ASP.NET, so I don't know how to do it. I'm pretty sure a quick google search will find you the answer. Then you need to make sure in that server CORS config, that special headers you want the client to be able to send are added to the CORS allowed headers. That's what the error is saying: that the headers are not included in the response header Access-Control-Allow-Headers. The response header would look like
Access-Control-Allow-Headers: X-Developer-Id, X-Api-Key, Time-Zone, Authorization
To learn more about CORS, see the MDN
First I would think that the API developers have to do something on the server side, like enabling that Time-Zone Header on CORS, however if that would be the case then we would get the same error on POSTMAN, but it works fine there
No, Postman does not have the same restrictions. It is a native desktop app. Fun fact: 99% of people who post questions on SO that hava a CORS problem, have somewhere in their post "...but it work with Postman!". So don't feel bad :-)
I think you should remove some of your headers and check you content-type so your request could be considered as a "simple request" and then won't trigger a CORS preflight as explained in the doc.
source:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#examples_of_access_control_scenarios
Apart from the headers automatically set by the user agent (for example, Connection, User-Agent, or the other headers defined in the Fetch spec as a forbidden header name), the only headers which are allowed to be manually set are those which the Fetch spec defines as a CORS-safelisted request-header, which are:
Accept
Accept-Language
Content-Language
Content-Type (please note the additional requirements below)

Categories

Resources