I have uploaded a Reactjs build to a subdomain (a web hosting service), but most of the Axios.get API requests are causing CORS errors. It does not seem to be the usual problem of allow-origin because that tests to be working.
I created .htaccess and put it in the subdomain root folder with the following code
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
which I confirmed working with the online test tool that gave this result:
"HTTP/1.0 200 OK =>
Connection => close
content-type => text/html
last-modified => Mon, 08 Aug 2022 03:52:36 GMT
accept-ranges => bytes
content-length => 644
date => Mon, 08 Aug 2022 02:39:20 GMT
server => LiteSpeed
access-control-allow-origin => *
alt-svc => h3=":443"; ma=2592000, h3-29=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, quic=":443"; ma=2592000; v="43,46""
when I test my URL with test-cors.org it also shows to be working:
Sending GET request to https://subdomain.mysite.com
Fired XHR event: loadstart
Fired XHR event: readystatechange
Fired XHR event: readystatechange
Fired XHR event: progress
Fired XHR event: readystatechange
Fired XHR event: load
XHR status: 200
XHR status text: OK
XHR exposed response headers:
content-length: 287
content-type: text/html
last-modified: Mon, 08 Aug 2022 03:52:36 GMT
Fired XHR event: loadend
but my site produces this error in the browser inspector:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
https://query2.finance.yahoo.com/v8/finance/chart/MYM=F?region=US&lang=en-US&includePrePost=&interval=15m&range=2d.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status
code: 200.
I can only think that the server cache needs clearing, as I found a lot of people with problems similar suddenly find it working after a few days, but I need to know if it is something I am doing wrong rather than wait days for a cache refresh.
Thanks to #jaromanda-x in the comments I resolved this by approaching it differently.
I cloned a CORS ANYWHERE proxy server on Heroku and added the subsequent URL created onto the front of my axios.get requests for my React build. After it tested working, I whitelisted it with only my domain address so that the public facing CORS proxy server would not be abused.
The steps were as follows:
create a free account with Heroku and download their CLI and login from there. I then cloned CORS ANYWHERE to my local machine from that CLI
git clone https://github.com/Rob--W/cors-anywhere
cd cors-anywhere
then created an app on heroku with
heroku create
it makes it with a random name you can then change via the platform or in the CLI.
Once that was done I deployed it from the CLI with
git push heroku master
This created a public address I was able to put on the front of my axios.get URL requests in React so they now looked like this
axios.get('https://mycorsproxyapp.herokuapp.com/https://query2.finance.yahoo.com/v8/finance/chart/MYM=F?region=US&lang=en-US&includePrePost=&interval=15m&range=2d')
That tested working fine on my live React build site, so the final part was to lock it down to only my site, and to limit the risk of my own site abusing it accidentally, I limited the rate to 60 per minute. This was done from the local Heroku CLI or in the platform settings.
heroku config:set -a mycorsproxyapp CORSANYWHERE_WHITELIST=https://myreactsite.com
heroku config:set -a mycorsproxyapp CORSANYWHERE_RATELIMIT="60 1"
I created a simple route in express using the code below.
const express = require("express");
const app = express();
app.get('/route1', (req, res) => {
res.send({ data: "Route 1" });
});
app.listen(3000);
When I run curl -X GET http://localhost:3000/route1, I am getting {"data":"Route 1"} as response.
However, I tried running curl -X OPTIONS http://localhost:3000/route1 to simulate a CORS pre-flight request. I received GET,HEAD as the response.
I was not able to find any documentation supporting this behaviour. Why did the above route respond to OPTIONS request?
(NOTE: I haven't used any other packages like CORS)
EDIT
Based on Quentin's answer, I tried issuing another OPTIONS request with relevant headers and with display headers flag in curl.
curl -i -X OPTIONS http://localhost:3000/route1 \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type,x-requested-with'
HTTP/1.1 200 OK
X-Powered-By: Express
Allow: GET,HEAD
Content-Type: text/html; charset=utf-8
Content-Length: 8
ETag: W/"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg"
Date: Wed, 03 Jul 2019 11:14:07 GMT
Connection: keep-alive
GET,HEAD
OPTIONS is a standard HTTP method with standard behaviour that has built-in support in Express.
The CORS spec layers additional semantics over the top of a regular OPTIONS request.
curl -X OPTIONS http://localhost:3000/route1 makes an OPTIONS request, but it isn't simulating a prefight request (as it is missing a bunch of request headers that are required by the CORS specification). The response you get to that request doesn't include any CORS response headers either.
Re edit:
I tried issuing another OPTIONS request with relevant headers
You missed out the Origin header, but as you can see, since you didn't set up CORS support in the Express app, the response still doesn't include any CORS response headers.
There are manu questions/answer regarding this but my issue not fixed from any solution there so I am writing here .
My node application is working fine on my dev environment but on prod when I request some api which take long time it throw 502 error .
On checking log I got this issue
2019/02/22 12:16:57 [error] 2575#0: *2 upstream prematurely closed
connection while reading response header from upstream, client:
172.31.85.97, server: , request: "GET /api//m2/v1/metrics_report?auth=asdsdffk HTTP/1.1", upstream:
"http://172.17.0.3:80/api/m2/v1/metrics_report?auth=asdsdffk", host:
"", referrer: ""
I think the error from nginx is indicating that connection is closed from server. Something must have broken in express application during the large data processing which has caused this. You can try to increase the timeouts in nginx to debug this properly -
location / {
proxy_read_timeout 1000s;
proxy_connect_timeout 1000s;
....
}
In my case, this was express misconfiguration. So, after reading and looking up here and there, I finally come up with the answer. Set the httpServer timeout just like the example below:
var httpServer = app.listen(8000, () =>
console.log('App is listening on port 8000.')
)
httpServer.setTimeout(1000)
I am attempting to use a Google Cloud provided VM to host a React.js front-end that contacts Spring Boot services (that are running in a Docker container). I was able to successfully contact the Spring Boot services, both running locally and remotely, while my React app was on my development machine. Now, however, I am attempting to move the React portion to the cloud as well. However, when I issue a request using the axios.js library:
componentDidMount() {
axios.get(this.props.baseEndpoint + "/inventory")
.then((res) => {
const inv : any = res.data;
console.log(res);
this.setState( {inventory: inv});
});
axios.get(this.props.baseEndpoint + "/category")
.then((res) => {
const cats : any = res.data;
console.log(res);
this.setState( {categories: cats});
});
}
where "baseEndpoint" is sourced from a config file:
export const BASE_URL : string = "http://localhost";
export const SEARCH_BASE : string = BASE_URL + ":8081/find";
export const INVENTORY_BASE : string = BASE_URL + ":8082";
the request fails.
With Firefox Developer's tools, a "Network Error" is logged to the console. However, whenever I switch over to the "Network" tab itself, it is as if the "Get" request is still pending or something. There is no response status (such as 500, 404, 200, etc), and both the "transferred" and "size" fields say 0. The response payload is empty.
The React app is served using a very simplistic Nginx configuration.
server { listen 80;
root /home/kelly/workspace/front-end/distr;
index index.html
location / {}
}
However, I can use curl to successfully GET the same endpoint (http://localhost:8082/category, for example) just fine. What might the issue be? I have also tried 127.0.0.0.
Thanks.
EDIT:
Request headers from Firefox Developer tools:
Accept
application/json, text/plain, */*
Accept-Encoding
gzip, deflate
Accept-Language
en-US,en;q=0.5
Connection
keep-alive
Host
localhost:8082
Origin
http://mysite
Referer
http://mysite/index.html
User-Agent
Mozilla/5.0 (X11; Linux x86_64…) Gecko/20100101 Firefox/58.0
Sample output from curl:
[{"id":1,"skuCode":"PS1","displayName":"PlayStation"},{"id":2,"skuCode":"PS2","displayName":"PlayStation 2"},{"id":3,"skuCode":"WII","displayName":"WII"},{"id":4,"skuCode":"GBC","displayName":"Gameboy Color"},{"id":5,"skuCode":"GBA","displayName":"Gameboy Advance"},{"id":6,"skuCode":"NDS","displayName":"Nintendo DS"},{"id":7,"skuCode":"N64","displayName":"Nintendo 64"},{"id":8,"skuCode":"GC","displayName":"Gamecube"},{"id":9,"skuCode":"SEG","displayName":"Sega Genesis"}]
EDIT TWO:
Networking is not my area of expertise, however, I tried running tcptrack -i eth0 while contacting my application. I see two requests to port 80 (presumably one for my HTML page and one for my .js file) from my local machine/browser. I also see multiple connections from my VM's IP to 169.254.169.254 (which based on this question, is simply a link-local address associated with cloud providers) and my SSH connection. However, I do not see any requests to port 8081, 8082, or anywhere else for that matter. Not sure if that might help provide some insight.
Thanks again.
I'm making an API call using Axios in a React Web app. However, I'm getting this error in Chrome:
XMLHttpRequest cannot load
https://example.restdb.io/rest/mock-data. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8080' is therefore not allowed
access.
{
axios
.get("https://example.restdb.io/rest/mock-data", {
headers: {
"x-apikey": "API_KEY",
},
responseType: "json",
})
.then((response) => {
this.setState({ tableData: response.data });
});
}
I have also read several answers on Stack Overflow about the same issue, titled Access-Control-Allow-Origin but still couldn't figure out how to solve this. I don't want to use an extension in Chrome or use a temporary hack to solve this. Please suggest the standard way of solving the above issue.
After trying out few answers I have tried with this,
headers: {
'x-apikey': '59a7ad19f5a9fa0808f11931',
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},
Now I get the error as,
Request header field Access-Control-Allow-Origin is not
allowed by Access-Control-Allow-Headers in preflight response
I'll have a go at this complicated subject.
What is origin?
The origin itself is the name of a host (scheme, hostname, and port) i.g. https://www.google.com or could be a locally opened file file:// etc.. It is where something (i.g. a web page) originated from. When you open your web browser and go to https://www.google.com, the origin of the web page that is displayed to you is https://www.google.com. You can see this in Chrome Dev Tools under Security:
The same applies for if you open a local HTML file via your file explorer (which is not served via a server):
What has this got to do with CORS issues?
When you open your browser and go to https://website.example, that website will have the origin of https://website.example. This website will most likely only fetch images, icons, js files and do API calls towards https://website.example, basically it is calling the same server as it was served from. It is doing calls to the same origin.
If you open your web browser and open a local HTML file and in that HTML file there is JavaScript which wants to do a request to Google for example, you get the following error:
The same-origin policy tells the browser to block cross-origin requests. In this instance origin null is trying to do a request to https://www.google.com (a cross-origin request). The browser will not allow this because of the CORS Policy which is set and that policy is that cross-origin requests is not allowed.
Same applies for if my page was served from a server on localhost:
Localhost server example
If we host our own localhost API server running on localhost:3000 with the following code:
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/hello', function (req, res) {
// res.header("Access-Control-Allow-Origin", "*");
res.send('Hello World');
})
app.listen(3000, () => {
console.log('alive');
})
And open a HTML file (that does a request to the localhost:3000 server) directory from the file explorer the following error will happen:
Since the web page was not served from the localhost server on localhost:3000 and via the file explorer the origin is not the same as the server API origin, hence a cross-origin request is being attempted. The browser is stopping this attempt due to CORS Policy.
But if we uncomment the commented line:
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/hello', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.send('Hello World');
})
app.listen(3000, () => {
console.log('alive');
})
And now try again:
It works, because the server which sends the HTTP response included now a header stating that it is OK for cross-origin requests to happen to the server, this means the browser will let it happen, hence no error.
Just to be clear, CORS policies are security features of modern day browsers, to protect people from harmful and malicious code.
How to fix things (One of the following)
Serve the page from the same origin as where the requests you are making reside (same host).
Allow the server to receive cross-origin requests by explicitly stating it in the response headers.
If using a reverse proxy such as Nginx, configure Nginx to send response headers that allow CORS.
Don't use a browser. Use cURL for example, it doesn't care about CORS Policies like browsers do and will get you what you want.
Example flow
Following is taken from: Cross-Origin Resource Sharing (CORS)
Remember, the same-origin policy tells the browser to block
cross-origin requests. When you want to get a public resource from a
different origin, the resource-providing server needs to tell the
browser "This origin where the request is coming from can access my
resource". The browser remembers that and allows cross-origin resource
sharing.
Step 1: client (browser) request When the browser is making a cross-origin request, the browser adds an Origin header with the
current origin (scheme, host, and port).
Step 2: server response On the server side, when a server sees this header, and wants to allow access, it needs to add an
Access-Control-Allow-Origin header to the response specifying the
requesting origin (or * to allow any origin.)
Step 3: browser receives response When the browser sees this response with an appropriate Access-Control-Allow-Origin header, the
browser allows the response data to be shared with the client site.
More links
Here is another good answer, more detailed as to what is happening: https://stackoverflow.com/a/10636765/1137669
If your backend support CORS, you probably need to add to your request this header:
headers: {"Access-Control-Allow-Origin": "*"}
[Update] Access-Control-Allow-Origin is a response header - so in order to enable CORS - you need to add this header to the response from your server.
But for the most cases better solution would be configuring the reverse proxy, so that your server would be able to redirect requests from the frontend to backend, without enabling CORS.
You can find documentation about CORS mechanism here:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
I had a similar problem and I found that in my case the withCredentials: true in the request was activating the CORS check while issuing the same in the header would avoid the check:
Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’
Do not use
withCredentials: true
but set
'Access-Control-Allow-Credentials':true
in the headers.
For Spring Boot - React js apps I added #CrossOrigin annotation on the controller and it works:
#CrossOrigin(origins = {"http://localhost:3000"})
#RestController
#RequestMapping("/api")
But take care to add localhost correct => 'http://localhost:3000', not with '/' at the end => 'http://localhost:3000/', this was my problem.
I had the same error. I solved it by installing CORS in my backend using npm i cors. You'll then need to add this to your code:
const cors = require('cors');
app.use(cors());
This fixed it for me; now I can post my forms using AJAX and without needing to add any customized headers.
For any one who used cors package change
const cors = require('cors');
app.use(cors());
to
const cors = require('cors');
app.use(cors({credentials: true, origin: 'http://localhost:5003'}));
change http://localhost:5003 to your client domain
Using the Access-Control-Allow-Origin header to the request won't help you in that case while this header can only be used on the response...
To make it work you should probably add this header to your response.You can also try to add the header crossorigin:true to your request.
First of all, CORS is definitely a server-side problem and not client-side but I was more than sure that server code was correct in my case since other apps were working using the same server on different domains. The solution for this described in more details in other answers.
My problem started when I started using axios with my custom instance. In my case, it was a very specific problem when we use a baseURL in axios instance and then try to make GET or POST calls from anywhere, axios adds a slash / between baseURL and request URL. This makes sense too, but it was the hidden problem. My Laravel server was redirecting to remove the trailing slash which was causing this problem.
In general, the pre-flight OPTIONS request doesn't like redirects. If your server is redirecting with 301 status code, it might be cached at different levels. So, definitely check for that and avoid it.
After a long time of trying to figure out how CORS works. I tried many way to fix it in my FE and BE code. Some ways CORS errors appearance, some ways the server didn't receive body from client, and other errors...
And finally got this way. I'm hoping this can help someone:
BE code (NodeJS + Express)
var express = require("express");
const cors = require("cors");
var app = express();
app.use(
cors({
origin: "*",
})
);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
next();
});
// your routers and codes
My FE code (JS):
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Connection: 'Keep-Alive',
Authorization: `Bearer test`,
},
body: JSON.stringify(data),
});
I imagine everyone knows what cors is and what it is for.
In a simple way and for example if you use nodejs and express for the management, enable it is like this
Dependency:
https://www.npmjs.com/package/cors
app.use (
cors ({
origin: "*",
... more
})
);
And for the problem of browser requests locally, it is only to install this extension of google chrome.
Name: Allow CORS: Access-Control-Allow-Origin
https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=es
This allows you to enable and disable cros in local, and problem solved.
npm i cors
const app = require('express')()
app.use(cors())
Above code worked for me.
You can create a new instance of axios with a custom config, and then use this new configured instance,
create a file with axios-configure.js, add this sharable exported method and use this preconfigured import, rather importing axios directly like we use traditionally,
import axios from 'axios';
import baseUrl from './data-service';
const app = axios.create({
baseURL: baseUrl,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
withCredentials: true
})
export default app;
use this exported function like,
import axios from '../YOUR_DIRECTORY/axios-configure';
axios.get();// wont throw cors
dont import axios from axios;
then use axios.get() it will dont throw cors worked for us,
NOTE this solution will work for them who facing CORS at local environment as local starts at 5000 and backend at 8080, but in production, build gets deployed from java 8080 no CORS in productions (Facing CORS at only local environment)
As I understand the problem is that request is sent from localhost:3000 to localhost:8080 and browser rejects such requests as CORS. So solution was to create proxy
My solution was :
import proxy from 'http-proxy-middleware'
app.use('/api/**', proxy({ target: "http://localhost:8080" }));
$ npm install cors
After installing cors from npm add the code below to your node app file. It solved my problem.
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
I had a similar problem when I tried to create the React Axios instance.
I resolved it using the below approach.
const instance = axios.create({
baseURL: "https://jsonplaceholder.typicode.com/",
withCredentials: false,
headers: {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
}
});
try it proxy
package.json add code:
"proxy":"https://localhost:port"
and restart npm enjoy
same code
const instance = axios.create({
baseURL: "/api/list",
});
You can use cors proxy in some specific cases - https://cors.sh
In node js(backend), Use cors npm module
$ npm install cors
Then add these lines to support Access-Control-Allow-Origin,
const express = require('express')
const app = express()
app.use(cors())
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'});
});
You can achieve the same, without requiring any external module
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
},
"proxy": "http://localhost:8080",
"devDependencies": {
use proxy in package.json