Why does CORS not make a request? - reactjs

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.

Related

CORS Error happens in api-key request in react js

I want to get api_kye and I use moqui framework in backend , use axios in react js project :
axios.get(SERVER_URL + '/rest/api_key', {
headers: {
Authorization: "Basic " + btoa(username + ":" + password) ,
'Content-Type' : 'application/x-www-form-urlencoded' ,
},
}).then(response => {})
then , when requested the below error happened :
Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin.
This is not a reactJS error, this is a problem with your backend code, you need to look at the Moqui docs to see how you can allow the origin you are calling from to access your API
Enable CORS in the server side
Let's head back to our server's app.js file.
app.get('/cors', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.send({ "msg": "This has CORS enabled 🎈" })
});
Also check the redirect URL in server side
Refer this link
when ever you send an HTTP request to an API the server response should include your domain in response header otherwise chrome will raise this error: "Access to XMLhttprequest has blocked for origin ...."
so first of all make sure that your domain is included in server code.
if it's included already then the reason could be that server can't process your response correctly. maybe it crashed so the response is corrupted and chrome can't find your domain in response header and it raises that error
So i have a solution for this but you may or may not be able to build it.
CORS is a security feature, you should be receiving requests thru your backend and not the browser directly in general...
IF the data is not sensitive and you want to open an endpoint to the world without getting CORS errors you can do one of two things
Set the CORS headers from the server side. You'll need to understand HTTP requests and headers. you set these from the server. enabling cross origin with * will work.
Build a proxy. I've done this in AWS API gateway, I'll link another post. works good. basically AWS will act as your back end and take the response with CORS blocked. you will then proxy the request and strip the CORS header. When you call the api you will actually call AWS which calls the API, then AWS will pass the response back to you with CORS enabled.
Angular No 'Access-Control-Allow-Origin'
just follow these steps and it will work.

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.

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]

redux isomorphic fetch Access-Control-Allow-Origin

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

Access-Control-Allow-Origin error but request goes through

I'm currently deploying a basic API to my live server and I'm running into (what I think is) a CORS problem but there is some behavior going on that I can't explain.
I'm communicating from an AngularJS front-end to a Laravel 5 (+ laravel-cors) back-end.
I started testing with a simple jQuery AJAX call (below) and when I make a request from my local Vagrant environment (http://dev.example.local/test.html) to http://api.example.com/v1/matches I get an error about Access-Control-Allow-Origin. The weird thing is that the request does come through because the information is stored in the database via the Laravel-based API correctly.
$.ajax({
method: 'POST',
url: 'http://api.example.com/v1/players',
data: {
"username": "username",
"first_name": "First",
"last_name": "Last",
"nickname": ""
}
}).always(function(r) {
console.log(r);
});
Error:
XMLHttpRequest cannot load http://api.example.com/v1/players. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://other.example.com' is therefore not allowed access.
The console.log(r) returns {readyState: 0, responseJSON: undefined, status: 0, statusText: "error"}
I developed the application locally using a Homestead VM (API) and a Vagrant environment (application) and it's working correctly within these environments...
Some observations:
Each of these requests shows up with Method: POST, Status: 200 OK, Type: xhr in my Chrome Developer Tools.
Tools like Postman and PhpStorm's RESTful service tester correctly execute the request and the data is added without errors.
Any ideas on how to further debug this problem are welcome... I've been trying to wrap my head around this for the entire day now and I just don't know what's causing it.
Your server must return an appropriate Access-Control-Allow-Origin header in the response. For example, if the request is being sent from http://stackoverflow.com, then your server must return this header: Access-Control-Allow-Origin: http://stackoverflow.com. You can determine, server-side, what the origin is by looking at the Origin header on the request. If your server does not return this header in the response, you will not have any access to the properties of the response browser-side (such as the status code, headers, or message body). The Same Origin Policy is at the center of this restriction.
The reason you are not seeing any similar issues when the request is sent by Postman or PhpStorm's RESTful service tester is due to the fact that these services do not send an Origin header with the request, as they are not subject to the Same Origin policy. By default, the browser will append this header to any cross-origin ajax requests, as browsers are subject to the Same Origin Policy. In my previous scenario, the request header would look like this: Origin: http://stackoverflow.com. Browsers that implement the CORS spec are required to add this request header so the server is able to determine if the origin of the request has been whitelisted for cross-origin ajax requests. If this is the case, the server will return the proper Access-Control-Allow-Origin header. If not, it can simply omit the header. Browsers that do not implement the CORS spec will simply refuse to send such an ajax request.
Regarding your bewilderment as to why the request is being sent in the first place, that comes down to a distinction between "simple" and "non-simple" CORS requests. For simple CORS requests, the request will always be sent to the server, but the client/JS will not be able to parse the response without proper acknowledgement from the server. Some CORS requests are not simple, so to speak. These are, for example, DELETE or PATCH requests, or POST/GET requests that contain non-standard headers (such as X-headers or a Content-Type of "application/json" as opposed to "multipart/form-data"). In other words, a request is not simple if it cannot be sent without JavaScript. For example, a <form> submit, or a GET request from a <script src="..."> will always send "simple" requests. For non-simple requests, the browser must "preflight" the request. This means that the browser sends an intermediate request, called a preflight, before the original request. This preflight request is an OPTIONS request. The server must than return headers in the response to this preflight that acknowledge any non-standard properties of the original request. If it does, then the browser will send the original request.
You can read more about preflighting and CORS in general on MDN.

Resources