http post request from Angular to Express server causes 404 error - node.js

I'm making a request to Azure function on local
url = 'http://localhost:7071/api/saveGraphDataFlow'
save(body) {
let headers = new HttpHeaders()
headers.append('Content-Type', 'application/json')
return this.httpClient.post(this.url, body, { headers: headers }).pipe(
map(res => {
return res
})
)
}
On my express server I'm adding cors to response
const createHandler = require("azure-function-express").createHandler;
const express = require("express");
const routers = require("./routes/routes");
const app = express();
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,PUT,POST,DELETE,OPTIONS");
next();
});
app.use("/api/", routers);
// Binds the express app to an Azure Function handler
module.exports = createHandler(app);
But when I send request I get this error :
Access to XMLHttpRequest at 'http://localhost:7071/api/saveGraphDataFlow' from origin 'http://localhost:4200' 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.
the preflight request is not passing

You could try to remove the extra slash from
app.use("/api/", routers);
and so it becomes:
app.use("/api", routers);
Also, as a sidenote, I have not seen your API router, and so maybe there is an extra slash or missing slash in there. Another thing I have noticed is that you're importing an entire folder (?) for your routers so make sure that you are importing a file at once. (i have not seen that, so this might not be true)

Related

CORS Issue: Unable to send post request using NodeJs and Angular

I am getting this message when trying to send a post request:
Access to XMLHttpRequest at 'http://localhost:3002/api/products/checkout' from origin
'http://localhost:4200' has been blocked by CORS policy: Request header field content-type
is not allowed by Access-Control-Allow-Headers in preflight response.
Right now I'm simply trying to send data to my backend and then log it in the console. Get requests work fine but for some reason I get that CORS error when trying post. Here is my code:
Angular code:
//api call
return this.http.post('http://localhost:3000/api/checkout', cart)
NodeJs code:
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Header',
'Origin, X-Requested-With, Content-Type, Accept');
res.setHeader(
'Access-Control-Allow-Methods',
'GET, POST, PATCH, DELETE, OPTIONS');
next();
})
app.post("/api/checkout", (req, res, next) => {
const cart = req.body;
console.log(cart)
res.status(201).json()
})
module.exports = app;
In the network calls I can see that Request Headers is:
Access-Control-Request-Headers: content-type
while Response Headers is:
Access-Control-Request-Headers: Origin, X-Requested-With, Content-Type, Accept
I'm not sure if content-type being lower case has anything to do with the issue.
You should use req.set instead, just change setHeader to set only. Here is the document https://expressjs.com/en/api.html#res.set
And if you just using localhost, there's another easier option, you can use proxy. More information can be found here https://angular.io/guide/build#proxying-to-a-backend-server
I think the problem that you wrote Access-Control-Allow-Header instead of Access-Control-Allow-Headers, but I cannot test it now.
Be aware that you need to serve OPTIONS requests too. Which is just responding with an empty message body using the same headers. You can get these kind of OPTIONS requests before PUT, PATCH, DELETE from certain HTTP clients e.g. from browsers too.

CORS blocking axios request with 'Authorization' Header and Data

Trying to send an axios post request from a Vue app (localhost) to my nodejs API (both localhost and heroku).
There are no issues receiving the response if the request is sent without data or headers, but as soon as I add them I get the following error:
Access to XMLHttpRequest at 'https://myapp.herokuapp.com/myendpoint' from origin 'http://localhost:8080'
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.
I have tried different options, both server and client side, as suggested on similar questions but had no success.
Client Request:
const apiUrl = 'https://myapp.herokuapp.com/myendpoint'
//const apiUrl = 'http://localhost:5000/myendpoint'
const token = Buffer.from(`${this.userid}:${this.password}`).toString('base64')
const data = {
'mydata': 'some data'
}
axios.post(apiUrl, data, {
headers: {
Authorization: "Basic " + token
}
}).then( res => {
console.log(res)
}).catch( err => {
console.log(err)
})
Server Endpoint:
app.post("/myendpoint", (req, res) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.send('This is the API\'s response')
})
Some of the answers I tried:
Response to preflight request doesn't pass access control check
Nodejs Express CORS issue with 'Access-Control-Allow-Origin'
https://www.moesif.com/blog/technical/cors/Authoritative-Guide-to-CORS-Cross-Origin-Resource-Sharing-for-REST-APIs/
CORS authorization issue while using axios
How to send authorization header with axios
I think it is better if you define your cors using a global middleware. First off, install cors by using npm i cors.
Then, I'll show an example of how that package could be used.
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
// your routes and things here...
Then, ensure that your front-end also uses withCredentials set to true in the axios request. This is done to ensure that the header is being sent properly.
axios.post(apiUrl, data, {
headers: {
Authorization: "Basic " + token
},
withCredentials: true,
}).then(() => ...);
Sometimes, if you define Access-Control-* manually, you might forget something. That's why I recommend you to use cors.

How to set Access-Control-Allow-Headers header in node-http-proxy

I am using the coinbase-pro library to make post request to the coinbase sandbox api through a form on localhost. I am trying to use node-http-proxy to get around a CORS error with no success. Ive been banging my head against the wall for a while on this, any help would be appreciated.
const express = require("express");
const httpProxy = require("http-proxy");
const port = 5050;
const app = express();
const proxy = httpProxy.createProxyServer({});
app.use(function(req, res) {
delete req.headers["origin"];
delete req.headers["referer"];
delete req.headers["host"];
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Content-type, cb-access-key,cb-access-passphrase,cb-access-sign,cb-access-timestamp"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET,POST,PUT,DELETE,OPTIONS"
);
const apiURL = 'https://api-public.sandbox.pro.coinbase.com'
proxy.web(req, res, { target: apiURL });
});
app.listen(port, () =>
console.log("Started proxy on port", port)
);
error:
Access to fetch at 'http://localhost:5050/orders' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field cb-access-passphrase is not allowed by Access-Control-Allow-Headers in preflight response.
The answer is here:
I think modifying the proxy response header is not covered in the current doc.
proxy.on('proxyRes', function(proxyRes, req, res) {
console.log('Raw [target] response', JSON.stringify(proxyRes.headers, true, 2));
proxyRes.headers['x-reverse-proxy'] = "custom-proxy";
proxyRes.headers['cache-control'] = "max-age=10000";
console.log('Updated [proxied] response', JSON.stringify(proxyRes.headers, true, 2));
// Do not use res.setHeader as they won't override headers that are already defined in proxyRes
// res.setHeader('cache-control', 'max-age=10000');
// res.setHeader('x-reverse-proxy', 'custom-proxy');
});
The key is to use proxyRes inside "proxyRes" event like proxyRes.headers[key] = value instead of relying on res.setHeader(key, value) as res.setHeader does not work when key is already exists among the proxy target response headers.

Cannot make requests on external URLs outside my localhost

I get this error when making a GET over 'https://www.google.com/'.
Failed to load https://www.google.com/: 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:4200' is therefore not allowed access. The response had HTTP status code 405.
On server side I use cors:
server.use(cors({
origin: '*',
credentials: true
}));
server.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,
Content-Type, Accept");
next();
});
server.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
next();
});
On client side I have a cookieService:
getCookies(URL) {
const headers = new Headers();
**headers.append('Access-Control-Allow-Origin', '*');**
return this.http.get(URL, { headers: headers }).map(res => res.json());
}
On an angular component I call this function:
searchCookies() {
this.cookieService.getCookies('https://www.google.com').subscribe();
}
Is there a way to add this header to the GET response? Or is there another way to acces to an external URL like https://www.google.com?
Thanks! :)
CORS headers, which you are adding to localhost via your server response, do not work for google - the whole idea of CORS is that the 3rd party server (in this case https://google.com) can defend itself from Cross Origin Resource Sharing.
TL;DR - https://google.com doesn't allow localhost to access the website. If you want to scrape the website - you'd have to access it from node.js itself, rather than client-side JS.

Google Maps API, fetch method having CORS issue

As stated in the title of this question, i'm having CORS issues with a fetch method. Here are the solutions i've tried. Obviously none have worked.
Actual console error:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' 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 tried to fix the issue via my Express server. I am configuring this before I establish my routes.
import cors from 'cors';
app.use(cors({
origin: '*',
}));
Also tried it this way.
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();
});
Client side service. Set {mode: 'cors'} object.
fetch(requestUrl, {mode: 'cors'}).then((response) => {
return response.json();
}).then((restaurants) => {
resolve(restaurants);
}).catch((err) => {
reject(err);
});
At this point, i'm lost. I'm just trying to get data back from google maps api. Any help would be grateful.

Resources