AngularJS cross domain request to separate ExpressJS App hosted on Heroku - node.js

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());

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())

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();
});

post request to Express.js api from another computer

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.

How to enable CORS for nodejs Express server?

I am trying to use an Ajax request at my front end:
$.ajax({
type: "GET",
url: "localhost:3000/send",
beforeSend:function(){
$(".loading_msg").hide();
},
complete:function(){
$(".loading_msg").show();
}
});
But when I load the page containing the script I get the following error:
Access to XMLHttpRequest at 'localhost:3000/send' from origin
'http://localhost:3000' has been blocked by CORS policy: Cross origin
requests are only supported for protocol schemes: http, data, chrome,
chrome-extension, https.
And
Unchecked runtime.lastError: The message port closed before a response
was received.
I have tried a lot of things like adding a middleware to express like:
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();
});
Which made no difference.
I also tried installing cors npm package and did
const cors=require('cors')
app.use(cors())
app.options('*', cors());
This made no difference either.
I also tried to change the ajax URL by adding https://
url: "https://localhost:3000/send",
While this does remove the CORS error, it gives me another error:
GET https://localhost:3000/send net::ERR_SSL_PROTOCOL_ERROR
How does sent an Ajax request from Nodejs express server while using a localhost?
Your cors error message clearly says you need to use http when making the request
$.ajax({
type: "GET",
url: "http://localhost:3000/send",
beforeSend:function(){
$(".loading_msg").hide();
},
complete:function(){
$(".loading_msg").show();
}
});
You will need this popular package, CORS.
Another workaround is to add backend to your webapp, using express server and use axios/request npm package to request data from API server using http, then you won't face any CORS issue.

File upload fails; 503 error (plus COR error)

I currently have access control allow origin set to *
When I try uploading a file without authorization cors blocks my request
I get these errors:
Access to XMLHttpRequest at 'https://serverurl.com' from origin 'https://fronendurl.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm using express and Node.js
This is my app.js file
app.use(cors());
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,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
next();
});
I'm assuming both https://fronendurl.com and https://serverurl.com are sitting on the same machine.
If you're creating a call, say AJAX to a different domain than your page is on from the same origin <= This gets blocked by the browser as it usually allows a request in the same origin for security reasons.
For a quick medicine I would tryout moesif's chrome plugin or firefox plugin.

Resources