redux isomorphic fetch Access-Control-Allow-Origin - reactjs

I have written a redux application which I am running locally using webpack-dev-server. (port 8080). I am trying to connect to a web service which is running locally at port 9000.
My code to connect to the web service is as follows
return fetch(`http://localhost:9000/movies/${dimensionName.toLowerCase()}list`)
.then(response => response.json())
.then(json =>
dispatch(receivedDimensionAttributesSuccess(dimensionName, json))
)
.catch(error =>
dispatch(receivedDimensionAttributesError(dimensionName, error))
);
This receives an error
Fetch API cannot load http://localhost:9000/movies/yearlist. No 'Access-
Control-Allow-Origin' header is present on the requested resource. Origin
'http://localhost:8080' is therefore not allowed access. If an opaque response
serves your needs, set the request's mode to 'no-cors' to fetch the resource
with CORS disabled.
I googled for the problem and found this thread
Access Control Allow Origin header not present with fetch api call
but I don't like the solution which involved switching to a different library/middleware altogether.
How can I solve the problem with the isomorphic fetch library.

look at me,this works
you must use
let header = new Headers({
'Access-Control-Allow-Origin':'*',
'Content-Type': 'multipart/form-data'
});
instead of
let defaultOptions = {
url:'',
method:'POST',
mode: 'cors',
headers:{
'Access-Control-Allow-Origin':'*'
},
body:null,
};
to enable cors

you can simply add {mode:'no-cors',} to disable the No 'Access-
Control-Allow-Origin' header. For more information you can refer the following url :
https://developers.google.com/web/ilt/pwa/working-with-the-fetch-api
return fetch(`http://localhost:9000/movies/${dimensionName.toLowerCase()}list`**,{mode:'no-cors'**,})
.then(response => response.json())

Access-Control-Allow-Origin is something you can control at client side. It is a security restriction for browsers that requires to be negotiated with the server.
A server can retrieve data from any end-point, but for browser apps this is different. For security reasons you are only allowed to load data via XHR from the same server you have loaded the web page.
If you need to load data from a different server (say an external API) the browser requires that server responds indicating you are allowed.
See description in the "Cross Domain Request" section on http://www.acuriousanimal.com/2011/01/27/working-with-the-javascript-xmlhttprequest-object.html

You can read this https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalFetch/fetch
fetch(url[, init])
set the init param to allow cross-domain request
try

Related

First API request fails because of CORS the following request are successful, REACT.js at the frontend and .NETCORE on the server side

I am making request to a .NetCore API from a React.js client, I have configured the CORS however every time a new device makes a request or if I clear my browser data the first request fails by this error
"Access to fetch at '...' from origin '...' 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."
The following requests are successful as expected since the configuration has been done on the server side.
fetch(GET_PAYMENT_URL, {
method: 'POST',
mode:'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(paymentUrlRequest),
})
.then((response) => response.json())
.then((data) => {
})
.catch(errorr => {
});
I expect the first request to be successful on a new device or even if the client clears browser data
As mentioned by #jub0bs in the comments,
the server side is configured to allow listed origins, thus the response header 'Access-Control-Allow-Origin' cannot be static or '*' for all, that's when we use 'Vary': 'Origin' so that the user agent will fetch a response that includes Access-Control-Allow-Origin, rather than using the cached response from the previous non-CORS request that lacks Access-Control-Allow-Origin.
Here is the link CORS protocol and HTTP caches

cors problem with react js request and jwt

i'm trying to fetch data with react from asp.net core 3.1 so i login with a request and get the jwt token. after that i want to send a request for getting data from api but it cause "preflight request "Access to fetch at 'https://localhost:44328/Address' from origin 'http://localhost:3000' 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.
apiAddress.js:24 GET https://localhost:44328/Address net::ERR_FAILED", i work with visual studio localhost as api server and configured startup like below:
//in ConfigureServices
services.AddCors(options =>
{
options.AddPolicy(name: AllowedOrigins,
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(hostName => true);
});
});
//in configure
app.UseCors(AllowedOrigins);
my fetch request is like below in reactjs:
const response = await fetch(url, {
'method': 'GET',
'mode': 'cors',
'credentials': 'include',
'headers': {
'Content-Type': 'application/json; charset=utf-8;',
//'Content-Type':'application/x-www-form-urlencoded',
'Authorization':`bearer ${token}`
}
});
and finally my controller is like below:
[ApiController, EnableCors("AllowedOrigins"), Authorize, Route("[controller]")]
public class AddressController : ControllerBase
what is wrong, i must mention other actions without [Authorize] attribute working ok, but action with it not works?!
some one mentioned that i should enable options in iis, but didn't explained how?
You will probably need to enable CORS on IIS. Here are steps how to do.
Open Internet Information Service (IIS) Manager.
Right click the site you want to enable CORS for and go to Properties.
Change to the HTTP Headers tab.
In the Custom HTTP headers section, click Add.
Enter Access-Control-Allow-Origin as the header name.
Enter * as the header value.
Click Ok twice.
Response to preflight request doesn't pass access control check: ....
other actions without [Authorize] attribute working ok, but action with it not works
In this doc, you would find:
A CORS preflight request is used to determine whether the resource being requested is set to be shared across origins by the server. And The OPTIONS requests are always anonymous, server would not correctly respond to the preflight request if anonymous authentification is not enabled.
While hosting on IIS server, you can try to install the IIS CORS module and configure for the site/application to make it work well.
Besides, if you'd like to make it work on local with IIS express, for testing purpose on CORS, you can try to allow anonymous access.
Or run it with kestrel and write custom middleware to correctly respond to the preflight request.

Why does CORS not make a request?

I have a problem with a CORS request
Access to fetch at 'https://webhook.site/f9087e12-b444-4e6b-9e64-06ba47b8c24e' from origin 'https://localhost:5001' 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.
My request:
fetch("https://webhook.site/f9087e12-b444-4e6b-9e64-06ba47b8c24e", {
method: 'get',
headers: new Headers({
'Access-Control-Allow-Origin': 'https://localhost:5001',
'Content-Type': 'application/json;charset=utf-8'
}),
})
.then(res => res.json())
.then(
(result) => {
console.log('res ' + result);
},
(error) => {
console.log('error ' + error);
}
)
I can’t figure out how to solve the problem.
CORS is a server side thing. Your browser is contacting webhook.site and saying "I want to download that thing f9087e12-b444-4e6b-9e64-06ba47b8c24e, what domains will you serve it to?" and webhook.site is saying e.g. "I'll only serve it to scripts that were downloaded from whatever.com" and your browser is thinking "hmm, well the script making the request was downloaded from localhost so.. denied"
You need to change the webhook.site server so it has an allow for localhost, not the client. It is the server response to the OPTIONS request that must contain the Access-Control-Allowed-Origin header, not the request from the client. Or you need to make the request without CORS in which case the browser will not make the options request.
CORS headers shall be returned from the server.
The server behind https://webhook.site/f9087e12-b444-4e6b-9e64-06ba47b8c24e shall return the header 'Access-Control-Allow-Origin': 'https://localhost:5001' in response to all requests, especially the OPTIONS request (preflight).
Best intro to the subject I have seen is https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
In a nutshell, the server shall decide if it allows CORS in general and to what resources.
The browser is responsible to protect the user by obeying to the rules defined by the server.
Hope it is helpful...
This is a browser's way of protecting it's users. Your request may be innocent, but imagine a scenario where the user goes to an innocent looking website which then uses http to send any password a user inputs to a thief. So the browser will only allow requests to the same domain or "origin".
There are ways around it, but the commonly accepted practice is to send the request to your server (localhost:5001) and your server sends a request to the other site and sends the response back to the browser.
That way all requests go through the domain that the user decided to trust by visiting.

Get method is converted to OPTIONS when hitting fetch api in React js

I am trying to hit below api and requires basic auth username and password and method allowed in this is only get
dispatch(requestBegin());
let apiPath = `xxxx/TEST/appservice/api/app/10/10000127201901`;
return fetch(apiPath, {
method: 'get',
headers : {
"contentType":"application/x-www-form-urlencoded",
"Authorization" : 'Basic '+btoa('xxx:xxx'),
},
})
.then((response) => {
dispatch(getEventsEnds(json));
})
.catch((error) => {
dispatch(getEventsEnds());
});
The error loged in console :
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:2200' is therefore not allowed
access. The response had HTTP status code 405. If an opaque response
serves your needs, set the request's mode to 'no-cors' to fetch the
resource with CORS disabled.
OPTIONS http://xxx/appservice/api/app/10/10000127201901 405 (Method
Not Allowed)
Can anyone please eplain when i m trying to hit get api then why is it showing options
That means your API server does not accept CORS request or requests originating from localhost.
Check out your API documentation but my guess is you won't be able to interact directly with it from your web app.
Your best bet is to use a proxy, you can develop one yourself or use something like node-http-proxy to proxy your API calls. (There are php or python equivalents)
The proxy server will be able to issue the requests and will then forward them to your app.
Suggested further reading: type understanding CORS on google and read more about it.
For local development, check out:
https://github.com/Rob--W/cors-anywhere
This issue occurs when the client api URL and server URL don't match, including the port number. In this case you need to enable your service for CORS which is cross origin resource sharing.
use npm install cors
refer this[refer][1]

Bad Request (400) When Trying to Authenticate Harvest API in React

So I'm building a status board for our internal use as developers here in the office. It will show number of commits, hours tracked, etc.
I am following this model for authenticating. After a user logs in with harvest it redirects them back to the app with the code param as a query string, I'm then taking that query string and passing it to a state to then do a fetch to get the access token (so that I can later pull API data).
What happens, is the login is successful but when you are redirected back to the app the fetch throws a Bad Request (400) error. I have tested in Postman and can get the correct response so I'm not sure what the issue is...
Here is some of the JS from the Main component that sets the states if there is a code param:
harvestState() {
// grab URL params
let urlParams = queryString.parse(location.search);
console.log(urlParams);
console.log(urlParams.code);
// set the state based on the paramater passed back
urlParams.code ? (
this.setState({
harvestcode: urlParams.code
})
) : (
this.setState({
harvestcode: 'none'
})
);
}
componentWillMount(){
this.harvestState();
}
And here is the fetch function in my Harvest component:
getHarvest(){
const clientSecret = 'XXXXXXXXXX';
// Set Harvest Headers
const harvestHeaders = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
method: 'POST',
mode: 'no-cors',
body: {
'code': this.props.code,
'client_id': this.props.clientid,
'client_secret': clientSecret,
'redirect_uri': 'http://dash.mycompany.me',
'grant_type': 'authorization_code'
}
};
fetch('https://mycompany.harvestapp.com/oauth2/token', harvestHeaders)
.then( response => response.json() )
.then( token => {
console.log(token);
} )
}
componentDidMount(){
if( this.props.code !== 'none' ){
this.getHarvest();
}
}
Is there something here that I am doing wrong? Why does it always return a bad request? Any help would be appreciated. Thank you!
At least one issue you have is that when you use mode: 'no-cors' you’re telling the browser to handle the response as an opaque response, which means that you’re telling the browser to not make any properties of the response object accessible from JavaScript.
So if you make a mode: 'no-cors' request, response => response.json() is going to fail.
The only purpose for no-cors in practice is in combination with Service Workers when you’re just caching resources (e.g., images) from responses, without need to get properties of the responses.
Anyway, given that the client Web app making the requests in your deployment is running from a different origin than the server the requests are sent to, browsers are going to block the requests unless the server responds with the necessary CORS headers—Access-Control-Allow-Origin, for a start. For an explanation, see the MDN article HTTP access control (CORS).
That is, browsers block cross-origin requests made from JavaScript unless the server the requests are sent to opts-in to allowing those, with the Access-Control-Allow-Origin, etc., response headers. The reason Postman doesn’t block such requests is that Postman is not an arbitrary Web app running at some specific origin on the Web but is instead a browser plugin that you’ve intentionally installed. So it’s not bound the cross-origin restrictions browser enforce for Web apps.

Resources