post request to Express.js api from another computer - node.js

I have a server running on localhost:3000, and I set my app.js to use the angular router when I try to access localhost:3000 in my browser
(example :app.use('/', express.static(path.join(__dirname, '/dist/Client')));)
When I make a post request to my api I do:
const headers = new Headers({
'Content-Type': 'application/json'
});
const options = new RequestOptions({
headers: headers
});
this.http.post('http://localhost:3000/api/someAction',{body},options)
.toPromise()
.then(//function)
Untill now everything is correct, but how can I make my server accessible from another computer. For example if another computer on the same network knows the private IP address of the server I want him to be able to access my app when he navigate to for example 192.168.1.10:3000. Right now I can access but all my http requests fail and I have the following error
Access to XMLHttpRequest at 'http://localhost:3000/api/someFunction'
from origin 'http://192.168.1.10:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It does not
have HTTP ok status.
In app.js I have the following:
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");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
next();
});

This is a CORS error message you're getting.
You can use the Express CORS middleware to allow calls from other origins to your server. Make sure to choose the right options to allow calls from your other PC.
https://expressjs.com/en/resources/middleware/cors.html
And also make sure to place the CORS middleware at the top of your application definition.
const app = express();
app.use(cors({ origin: "*" })); // Do this first
//... the rest of your routes and handlers and middlewares
From your local machine where things seem to work correctly, open your Chrome Dev Tools, and make sure OPTION calls are being made and fulfilled successfully, and that proper headers are being returned.
Lastly, from a security perspective, remove or restrict the CORS options as much as possible for your production environment. Only use flexible CORS policy during development and testing.

Related

CORS policy issue

I am in a team doing a client-server application. We are using Node.js (v12.18) in the backend as an API, and React (v16.13) for the frontend. Recently I've found this bug related to the CORS policy. I'm trying to send a POST request, deleting one resource in the database and when trying to delete it, this is the error I get:
Access to fetch at 'http://localhost:8080/clientes/eliminar' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
As far as I researched in forums and discussions I always find the same resolution, which is using the "Access-Control-Allow" headers, but we are already using them. I tried to change the POST method by a DELETE method when doing the request, but I find the same issue.
The headers that we are currently using in the backend, in case someone wonders what we have.
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Methods", "GET, POST");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
next();
});
The sites I visited in order to solve the problem were pretty much the same as this one
TYSM for reading until here and ask for more information you need. Every piece of help is appreciated.
Have you already tried to add CORS to the project and use it as a middleware?
//...
const cors = require('cors')
//...
app.use(cors())

How to solve the issue response to preflight request doesnt pass access control check error?

I have a angular code in a VM, node code in another VM. I need to make an API call from this angular VM to node VM. I have included the cors module also. But still while making an API call, getting an error like
"access to xmlhttprequest at 'http:IP1' from origin 'http:IP2' has been blocked by CORS policy: Response to preflight request doesnt pass access control check: No 'Access control".
I have set header like this also,
app.use(function(req,res,next) {
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods','POST');
res.setHeader('Access-Control-Allow-Headers','X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials',true);
next();
});
app.use(cors());
But still I'm facing an error. Can anybody tell me how to solve this error?
Try to set explicitly your localhost and add desired types of methods:
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
// desired types of methods
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
UPDATE:
For example, your node server is hosted at http://127.0.0.1:8000. Then your Angular Application should be http://127.0.0.1:4200.
UPDATE 1:
npm install --save cors
and then:
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());

Getting 'has been blocked by CORS policy' while trying to upload file

I was trying to set a ui for uploading excel file using angular8. The front and backend (nodejs) applications are running in two different ports. While clicking upload button i am getting errors.
Have tried adding this code:
app.use(cors());
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
still same error
typescript:
url_='http://localhost:3000/product/upload-exel'
public uploader :FileUploader = new FileUploader({
url:this.url_
});
html:
<input type="file" id="file"
ng2FileSelect [uploader]="uploader"
[(ngModel)]="path">
OPTIONS http://localhost:3000/product/upload-exel 404 (Not Found)
Access to XMLHttpRequest at 'http://localhost:3000/product/upload-exel' from origin 'http://localhost:4000' 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.
My code is deployed on AWS and this thing worked for me:
Besides all the technical things (to be added) which are stated on several other Q/A make sure that your function returns the response to the front-end within 29 seconds. This is the default timeout (and maximum timeout) set for your response. After fixing this I was able to break the CORS error.
The error message indicates that 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'.
If your backend server is http://localhost:3000/ and your client frontend is running on http://localhost:4000/, then your backend headers should be:
Backend Server
app.use(cors());
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4000/');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST,
OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
In your backend, Since you are using cors module, you can do this and it is safe
var cors = require('cors')
var app = express()
//set options for cors
//add your frontend addresson in the origin
//for testing add localhost and port
var corsOptions = {
origin: 'http://localhost:3000',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
//for specific endpoint enable cors
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')
})```
This may happen also when using nginx on Mac (homebrew)
If you enable debug error loging you can see this error when uploading - this is what's actually causing the CORS error:
25 open() "/usr/local/var/run/nginx/client_body_temp/0000000001" failed (13: Permission denied)
That may be a bug in the homebrew nginx: https://github.com/denji/homebrew-nginx/issues/124
Not sure if this is the proper fix, but I was able to get it to work this way:
sudo chown YOUR-MACOS-USER /usr/local/var/run/nginx/client_body_temp/
After that restart nginx

CORS error on localhost, Is that a normal?

I am running a node.js API on port 8000 which is connected locally to mongo db.
I then start my react server on port 3000 and straight away in console I get the error:
Access to XMLHttpRequest at 'http://localhost:8000/api/hero/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Is this normal for a localhost setup?
Yes, because CORS doesn't care about localhost in any specific way. Instead, the combination (!) of hostname and port is being used to differ between multiple parties.
Hence, for CORS, localhost:3000 is something completely different than localhost:8000, so, yes, this is normal.
I guess localhost:3000 is running webpack dev server? If so the simplest way to resolve this is to config your webpack dev server to proxy the request for you, so no need to add CORS handling on your own express server
in your webpack.conf.js, add
devServer: {
proxy: {
'/api': 'http://localhost:8000'
}
}
Access-Control-Allow-Origin block all request, that are not defined in your node.js API
Add the following lines to your node.js server. This allows you to access the api from every url.
this.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, authorization");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
next();
});

AngularJS cross domain request to separate ExpressJS App hosted on Heroku

I have a stand-alone ExpressJS API that I have built that should be able to service mobile apps and web apps. I'm trying to test the API using a simple AngularJS client app that I have built. The API service runs fine when I host it locally.
I'm getting Cross Domain Request errors when trying to make a GET call to the API hosted on my external server. I'm using Chrome v39
EDIT: my error turns out to be an incorrect URL reference to my heroku API. Please see my answer, below.
XMLHttpRequest cannot load http://myservice.heroku.com/some-api-endpoint?request-parameter=value. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:5001 is therefore not allowed access.
After reading and scanning numerous articles, I've tried the following:
CORS Code on the API
Added to app.js
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Max-Age", "1728000");
res.header("Access-Control-Expose-Headers", "Cache-Control, Pragma, Origin, X-Requested-With, Content-Type, Accept");
if (req.method === 'OPTIONS') {
res.statusCode = 204;
return res.end();
} else {
return next();
}
});
CORS Code on the API (Attempt 2)
Using the CORS node_module instead of the above, yields the same errors
Added to Package.json
"cors" : "~2.5.2"
Added to app.js
var cors = require('cors');
app.use(cors());
Client Code (Attempt 1)
$http({
url: 'http://myservice.heroku.com/some-api-endpoint?request-parameter=value',
method: 'GET',
headers : {
"Origin" : "myclient.heroku.com",
"Access-Control-Expose-Headers": "X-Requested-With",
"Access-Control-Request-Method" : "GET",
"Access-Control-Request-Headers" : "Origin, X-Requested-With, Content-Type, Accept"
}
})
Errors in the chrome dev console:
Refused to set unsafe header "Origin" angular.js:9625
Refused to set unsafe header "Access-Control-Request-Method" angular.js:9625
Refused to set unsafe header "Access-Control-Request-Headers" angular.js:9625
XMLHttpRequest cannot load http://myservice.heroku.com/some-api-endpoint?request-parameter=value, which is disallowed for cross-origin requests that require preflight. (index):1
Client Code (Attempt 2)
thePath = 'http://myservice.heroku.com/some-api-endpoint?request-parameter=value'
+'&callback=JSON_CALLBACK';
$http.jsonp(thePath)
.success(function(data){
console.log(data);
});
Errors received in the Chrome Dev Console:
Uncaught SyntaxError: Unexpected token : endpoint?request-parameter=value&callback=angular.callbacks_0:1
This has been stumping me for two days. Any help is appreciated!
The error turned out to be the reference to applications hosted on Heroku. I was attempting to make my get requests to myapp.heroku.com and not myapp.herokuapp.com. This is a subtle difference that caused there error.
Using cURL or typing in the request into the browser's address bar for myapp.heroku.com will redirect your request to myapp.herokuapp.com and complete the request successfully. However, made from Angular.js $http() function resulted in the Cross Domain error.
The simplest problems seem to cause the most confusion.
You are taking a convoluted route for CORS. Use nodejs CORS middleware to do your stuff....
add,
"cors": "^2.5.1",
to your dependencies in package.json & in app module,
var cors = require('cors');
//add cors to do the cross site requests
app.use(cors());

Resources