CORS error even with cors nom package installed - node.js

I am using React Filepond and the uploading part is working fine. But when I go to an existing record and try to display the image, I get a CORS error:
Access to XMLHttpRequest at 'http://localhost:8000/img/myImg.jpg'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
in app.js on my node server I have the below but I still get the cors error using the cors package
const cors = require("cors");
app.use(cors());
app.options("*", cors());
In React I have the following:
state = {
data: {
title: "",
bgImg: ""
},
errors: {},
files: [
{
source: "myImg.jpg",
options: {
type: "local"
}
}
]
};
<FilePond
ref={ref => (this.pond = ref)}
files={this.state.files}
allowMultiple={false}
maxFiles={1}
name="bgImg"
server={{
process: "http://localhost:8000/api/uploads/",
load: "http://localhost:8000/img/"
}}
oninit={() => this.handleInit()}
onupdatefiles={fileItems => {
this.setState({
files: fileItems.map(fileItem => fileItem.file)
});
}}
/>
In package.json I have also added a proxy:
"proxy": "http://localhost:8000/img",
Network tab -> headers tab shows
Request URL: http://localhost:8000/img/myImg.jpg
Referrer Policy: no-referrer-when-downgrade
Provisional headers are shown
Referer: http://localhost:3000/home-banner

Try installing cors plugin in your browser and access the api. Hope this helps..
const cors = require('cors')
const corsOptions = {
origin: 'http://localhost:8000'
}
app.get('/img', cors(corsOptions), (req, res, next) => {
//...
})

Related

The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute wont work

I am having this problem when trying to use withCredentials that it tells me that I need
Access to XMLHttpRequest at 'http://localhost:3005/api/v1/user' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Uncaught (in promise) AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
async function getUser() {
const user = await axios.get("http://localhost:3005/api/v1/user", {
withCredentials: true, headers: {
'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'
}
});
console.log(user)
}
useEffect(() => {
getUser();
}, [])
Researching this people are telling me that I need to activate cors on the server. But from what I can tell I have already done that by doing this + npm I cors.
const cors = require('cors')
var app = express();
const corsOptions ={
origin:'*',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions))
If I remove the withCredentials everything works fine the problem is that I need the connect.sid cookie on the server in order to log in the user.
I have had this problem before. Solved it by changing the * to ['http://localhost:3000']
So your code should say:
const cors = require('cors')
var app = express();
const corsOptions ={
origin:['http://localhost:3000'],
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions))

Cors error strict-origin-when-cross-origin simple nodeJS-reactJS project

I'm trying to upload image to Cloundinary, but an error occurred with status code 500 relating to cors though i had set the server to allow all origin.
The error message is:
POST http://localhost:5000/my-route-upload 500 (Internal Server Error)
here is my POST function :
const cloudinaryUpload = (fileToUpload) => {
return axios.post(API_URL + '/cloudinary-upload', fileToUpload)
.then(res => console.log(res))
.catch(err => {
console.log(err)
console.log("cannot post")
}); }
In server side, I had added the following block in App.JS
const cors = require('cors');
var app = express();
app.use(cors({
origin: "*",
})
);
Those codes did execute, i tried modify the origin to the specific one like http://127.0.0.1:3001 (my client port is 3000). Then it came out another error message
Back to the first error, in tab Network/Headers :
Request URL: http://localhost:5000/cloudinary-upload
Request Method: POST
Status Code: 500
Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: *
Host: localhost:5000
Origin: http://127.0.0.1:3000
I don't know why it didn't work. I use create-react-app for client and Express generator for server
Maybe you should add the content-type header to your Axios request. Like this.
const res = await axios.post('url', data, {
headers: {
'content-type': 'application/json'
}
});
Setup a proxy for your server from your client
Proxy can be a simple
"proxy": "http://localhost:5000" in your package.json, where all unknown requests will be proxied to localhost:5000
Essentially you need to call the api from client as /my-route-upload instead of http://localhost:5000/my-route-upload.
But preferred method would be to add a file called src/setupProxy.js
and
$ npm install http-proxy-middleware --save
add this to the file
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};```
Also look at enabling cors in express
https://enable-cors.org/server_expressjs.html
const cors = require('cors');
var app = express();
app.use(cors());
try this
This middleware helps to avoid cross-platform error
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
});
Set this header middleware on your root file above your all routes in the express app, Update this code block with your server cors block in AppJS

Add Access-Control-Allow-Origin to header on fetch method by chrome terminal

I am trying to test CORS on my simple web service.
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({ msg: 'This is CORS-enabled for only example.com.' })
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
In the chrome terminal by using fetch command I want to call my service :
fetch("http://localhost/products/1", { credentials: 'include', headers: {
'Content-Type': 'application/json', 'Access-Control-Allow-Origin': 'http://example.com'
},}).then(req => req.text()).then(console.log)
but I got error:
search:1 Access to fetch at 'http://localhost/products/1' from origin 'https://www.google.com' 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.
VM331:1 GET http://localhost/products/1 net::ERR_FAILED
I added Access-Control-Allow-Origin to my request but not works!
Check the different cases I have mentioned below, Your Question falls under CASE 1, If in case you are trying to make a request from a website in local or in production, you can refer other cases.
CASE 1
If you are planning only to make requests from tabs, the it is best to set origin property inside corsOption to "*" like this.
origin: "*"
CASE 2
If you want to send request to the server from an application running on your local host then add "http://localhost:(port of Front end app)" to the origin property
origin: "http://localhost:<website_port>"
CASE 3
If your front end app is deployed somewhere then the domain of that website should be added to the origin property like this
origin: "www.mywebsite.com"
CASE 4
Mutiple websites needs to consume the API, then add the an array of domains in the origin property like this
origin: ['domain1', 'domain2', ...]
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://localhost:<the port>', //? can be a array of domains too
optionsSuccessStatus: 200
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({ msg: 'This is CORS-enabled for only example.com.' })
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
If you need to whitelist localhost only on development then you can try the following:
const corsOptions = {
origin: process.env.NODE_ENV === 'DEVELOPMENT' ? true : /https:.*?\.?domain\.com/,
}
In production it'll allow your domain and sub-domains only.
The domain you specify in corsOptions will be allowed to make requests to your server. In your case you are using browser's terminal and hence the domain you are on will be taken as origin. Since you have Google open, you must set that in your corOptions:
const corsOptions = {
origin: 'https://google.com',
optionsSuccessStatus: 200
}
Also specify the port your express app is running on:
Access to fetch at 'http://localhost/products/1' from origin 'https://www.google.com' has been blocked by CORS policy
The URL should be http://localhost:80/products/1 in this case.
If you'll be using browser terminal for testing then I'd recommend setting the origin to true which will allow requests from any origin:
const corsOption = {
origin: true
}
If you don't have a web app and just need to test the API, consider using API clients like Postman or Insomnia. You can read more about CORS configuration in the documentation.

getting CORS and network error while calling axios post request using Vue js

I am getting error while calling axios post request. But it works properly on postman.
The code I used for calling the request is
methods : {
displayData(){
var config = {
method: 'post',
url: 'http://localhost:5000/api/request/displayRequest',
headers: {
'Content-Type': 'application/json'
},
data : JSON.parse(JSON.stringify(this.user._id))
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
},
async mounted(){
this.displayData()
}
I have already implemented CORS on the back-end in server.js
// Cors Middleware
const cors = require('cors');
app.use(cors());
app.options("*", cors());
app.use(
cors({
origin: (origin, callback) => callback(null, true), // you can control it based on condition.
credentials: true, // if using cookie sessions.
})
);
in your backend use this :
npm i cors
and in your express backend entrypoint:
const cors = require("cors");
app.use(cors());
app.options("*", cors());
You are running your front-end on localhost and using some port. Also, your back-end is running on localhost, port 5000. But your front-end application can not access any other port due to CORS policy. You can solve this problem in the back-end if you are using Node JS.
Install cors by the following command:
npm i cors
Then on your server file, change your app by
app.use(cors());
N.B. If you used React js, you could use http-proxy-middleware. Just create a file inside the src directory named "setupProxy.js". and add the following lines.
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api",
createProxyMiddleware({
target: "http://localhost:5000/",
})
);
};
Don't forget to change the port in this file into the port of your server.

How to fix "Response to preflight request doesn't pass access control check: It does not have HTTP ok status" error in react app with nodejs api

I have been trying to do an api call (nodejs with express running on localhost) from a react app running in the browser over a local dev server (web-pack dev server). Everything was working well until I tried to call the api. They are both running on separate ports.
I have tried adding the cors headers (Recommended by MDN) to both the post call (from the app in browser) and to the response from the Nodejs API but neither of these solved the issue.
Code for the api call (in browser):
const headers = {
'Content-Type': 'application/json',
'access-token': '',
'Access-Control-Allow-Origin': '*',
}
export default async () => {
try {
const body = JSON.stringify({
test: true,
})
const response = await fetch('http://localhost:1337/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
console.log(response)
} catch (e) {
return e
}
}
API Middleware (in nodejs):
// Verify All Requests
app.use(VerifyToken)
// Compress
app.use(compression())
// Helmet middlware
app.use(helmet())
// Body Parser
app.use(bodyParser.urlencoded({
extended: false,
}))
app.use(bodyParser.json())
The expected result is to just give a 200 status code and respond with the data.
The actual output is:
OPTIONS http://localhost:1337/internal/provider/check_email_exist 404 (Not Found)
Access to fetch at 'http://localhost:1337/internal/provider/check_email_exist' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Since you're using webpack-dev-server you can use the proxy option DevServerProxy.
Your configuration will look like this:
// webpack.config.js
devServer: {
proxy: {
'/internal': 'http://localhost:1337'
}
}
Since I can't see your express routes on your question I'm speculating about the proxy route if your API lives on /internal endpoint then you should modify your React code like this:
const response = await fetch('/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
As you can see I ommited the https://localhost:1337 because the proxy option from webpack-dev-server will handle this and it will redirect to http://localhost:1337. Hope this will help you. Cheers, sigfried.
EDIT
As the comment on your question pointed out you should set the headers on your express server, not the client, for this task you can use the cors-middleware package.
Maybe this can help if you face with preflight errors.
My full config:
const cors = require('cors');
const express = require('express');
const { createProxyMiddleware: proxy } = require('http-proxy-middleware');
...
const logLevel = 'info';
const ip = require('ip').address();
const proxyOptions = {
xfwd: true,
target,
changeOrigin: true,
logLevel,
cookieDomainRewrite: {
'*': 'localhost',
},
headers: {
'X-Forwarded-For': ip,
'X-Node': 'true',
},
};
const backNginxApp = express();
backNginxApp.use(
cors({
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
origin: 'http://localhost:3000',
optionsSuccessStatus: 200,
credentials: true,
})
);
backNginxApp.use('/api', proxy(proxyOptions));
API: const target = 'https://someapi.com'
Local development running at: http://localhost:3000

Resources