Fetch with post data to expressjs leads to 404 server not found - javascript

Having a react frontend with my own expressjs api backend.
Express v. 4.16.0
Using fetch on the react frontend to get data works just fine.
fetch('/desResData')
.then(res => {....}
As soon as I try to post some data with the request I get: "POST http://localhost:3000/desResData 404 (Not Found)"
Code:
fetch('/desResData',
{
method: 'POST',
body: { product: "test" }, // tried JSON.stringify as well
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
)
.then(res => {....}
Roughly spoken I can have static communication from front to backend but I cant parametrize my requests.
ExpressJS:
router.get('/', async function (req, res, next) {
console.log(req.body) // tried with using req and without using it
findByProduct("product") // some async db operation // this part is working fine while fetching without any post parameters
.then(data => {
res.json()
})

You have to write router.post (not router.get) to process an HTTP POST request.
Notice the method of your fetch is POST. But you wrote router.get which handles a request where the method is GET.
If a POST request comes in for a route that doesn't exist, express will give 404. This applies even if there is a GET handler for the same route.
(Hint: you can have separate GET, POST, PUT, DELETE, etc. handlers for the same route by using .get, .post, .put, .delete, etc.)

add this in your server code :
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, HEAD');
next();
});
inside package.json of your react code :
"proxy": "http://localhost:serverport", <-- server port will be port of your node-express server

Related

Access to fetch at *** from origin *** has been blocked by CORS policy: No 'Access-Control-Allow-Origin'

I have error
Access to fetch at 'http://localhost:5000/admin/authenticate' from origin 'http://localhost:3000' has been blocked by CORS policy: 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.
My ApiManager
function login(username, password) {
const requestOptions = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*' },
body: JSON.stringify({ username, password })};
return fetch(`http://localhost:5000/admin/authenticate`, requestOptions)
.then(handleResponse)
.then(user => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('user', JSON.stringify(user));
return user;
}
);
}
In Backend Asp.Net Core 2.2 (Startup.cs) I write:
services.AddCors(options =>
{
options.AddPolicy(
_corsName,
builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials(); });}
);
i tried anerco's answer but it didn't work for me, i found this article, it has a very similar solution but with .SetIsOriginAllowed(origin => true) added and .AllowAnyOrigin() removed.
So you should add this code to your Configure method in startup class :
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true) // allow any origin
.AllowCredentials()); // allow credentials
I recommend reading the article to get a better understanding of all of this, it's very short and straight to the point.
Hi I'm new on this topic but because I've got this error last week I tried enabling options method and the first part resolved .
This error happens due to policy and security issues but now I refer you to get the status code and in my case it was 405 error which means now we have to change our headers in the request to allow all methods and origins (no way )
but it doesn't help me out.
So I figured out that I have enabled cookie encryption and session (wide of the point) in my app for my API therefore I disabled them and cleared browser cookie as well .
So try using these:
Clear your cookies and add Access-Control-Allow-Origin': '*' by Mod Header extension and try again to check the fix .
mod header - your header (client)
Try using a middle interface to control your request and guide them into the special rules
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
According to this site : https://medium.com/#dtkatz/3-ways-to-fix-the-cors-error-and-how-access-control-allow-origin-works-d97d55946d9
Try this:
on Startup.cs => Confirgure add:
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());
FOR NODE EXPRESS GRAPHQL RESTAPI
Add this header middleware to avoid CORS and any POST or OPTIONS 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");
if (req.method === "OPTIONS") {
return res.sendStatus(200);
}
next();
});
If your server is express.js based, add these lines to the server:
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();
})
In my case, I was trying to make a blob from an image stored on the API (the server) so the URL was pointing to that resource, in that API's program.cs class, I already had a CORS policy, but I'd get the exact error as you said. After I read the Microsoft docs (read the first paragraph that you see) about this issue, it is said that if you want to access a resource on the server, by using JavaScript (which is what I was trying to do), then you must call the app.UseCors(); BEFORE the app.UseStaticFiles(); which is typically the opposite.
My program.cs:
const string corsPolicyName = "ApiCORS";
builder.Services.AddCors(options =>
{
options.AddPolicy(corsPolicyName, policy =>
{
policy.WithOrigins("https://localhost:7212");
});
});
...
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI(settings =>
{
settings.DisplayRequestDuration();
settings.EnableTryItOutByDefault();
});
app.UseHttpsRedirection();
app.UseCors(corsPolicyName); // 👈 This should be above the UseStaticFiles();
app.UseStaticFiles(); // 👈 Below the UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseApiCustomExceptionHandler();
app.MapControllers();
app.Run();
There is a bug in Chrome that has affected users for years now, it can be found here.
You can use the Chrome extension Allow-Control-Allow-Origin: * found here: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi
Alternatively you can use http://lacolhost.com/ which points to 127.0.0.1 like localhost.

"Access-Control-Allow-Origin" CORS issue when using Vue.js for client side and Express for server side

I'm trying to make a call to my API on Jazz using Vue.js and Axios, but I am getting the following error:
Access to XMLHttpRequest at 'https://jazz.api.com/api/extra_stuff
_here' from origin 'http://localhost' 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've been looking at other solutions like https://enable-cors.org/server_expressjs.html or adding
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": "true"
to my code and it still didn't work. Even if I do the wildcard for the Access-Control-Allow-Origin, I still get the CORS issue and cannot call my API. I am using Vue and Typescript for the client side and managed to get Express working for my server side. Here is a code snippet of my Axios API call:
return Axios.post('https://jazz.api.com/api/extra_stuff_here', context.getters.getRequest,
{
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": "true"
}
}
)
This is where I am calling my API in this TypeScript file and here is my server.js:
var express = require('express');
var path = require('path');
var cors = require('cors');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var app = express();
app.use(morgan('dev'));
app.use(cors());
app.use(bodyParser.json());
var publicRoot = './dist';
//app.use(express.static(path.join(__dirname, '/dist')));
app.use(express.static(publicRoot));
app.get('/', function (req, res) {
res.sendFile("index.html", { root: publicRoot });
});
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Authorization");
res.header("Content-Type", "application/json");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
app.listen(process.env.PORT || 80, function() {
console.log("listening on port 80");
});
No matter what I seem to do, I cannot figure out this CORS issue. Before I added express to my application, I still got the same issue, thinking that maybe express on the server side would fix the CORS issue. However it didn't help. Beforehand, I was running my Vue application by doing npm run serve. But any help would be great! Could it possibility be an issue with Jazz?
You’ve added the cors middleware but haven’t enabled it for OPTIONS requests
app.options('*', cors())
Try adding something like this to your server to enable it.
You can read further in the express docs here
https://expressjs.com/en/resources/middleware/cors.html
Update: I didn't manage to fix the CORS issue with Axios, but I did manage to find a workaround for this. Instead of using the Axios library, I am using fetch to call the API. Since all I need to do with my request call is to pass in parameters and get back data based on the parameters, my application works with fetch. While I was doing my research, I saw that there may be issues or limitations using fetch? But hey, it works for me so I'll be sticking with this solution. Here is my code as reference for anyone:
return fetch('https://dev.jazz.com/api/stuff_goes_here', {
method: 'post',
body: JSON.stringify(<request object goes here>)
}).then((res) => res.json())
.then((data) => {
return data;
}).catch((err)=>console.log(err))

Two request being sent from browser but only localhost is called

I have an node js API.
app.post('/myapi', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Request-With");
res.header("Content-Type", "application/json");
res.header("Accept", "application/json");
* do something *
res.json({ api : "api called successfully" });
});
I have a html code placed in the public folder. I am using express to run both the html code and backend APIs.
My html code has request fetch as,
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json, text/plain, */*');
var options = {
method: 'POST',
body: JSON.stringify(loginDetails),
headers: headers,
mode: 'no-cors'
};
fetch('http://localhost:3001/myapi', options)
.then(function (response) {
console.log(response);
res=response.statusCode;
// return response
if (res==0) {
window.location.assign("http://localhost:3001/home.html");
}
});
When I run the code in browser. When I click on a button that calls the above frontend code. It sends two request. Both the call fails. One is localhost request which is document call and other is the API call. But there is no response in the API call.
I was getting response in UI from the / call,
cannot POST/
So I tried adding following code,
app.post('/', function (req, res) {
res.json({ "status": "successfull" });
});
Now also there is two calls but UI returns {status : successfull} (output of /). But it is not returning output of /myapi.
Can someone please help?
I am getting an infinity initiator for localhost document. See the screenshot.
Append any unique parameter to request to avoid sending cached version of request.
/api/name?id=<unique_param>
You can find more details here and here.

Failed to fetch: Request requires preflight, which is disallowed to follow cross-origin redirect

I'm using Express for webserver, and using isomorphic-fetch module from client to using XHR.
I have three servers for my web application:
Port 3000 -> Admin Website
Port 3001 -> Public Website
Port 3002 -> API Server
API Server has resources named "skills" which has some data, and get it like this:
GET http://mydomain:3002/skills
it returns JSON data.
But when I request to 3002 from 3000/3001, it fails with this message:
Fetch API cannot load http://example.me:3002/skills. Redirect from 'http://example.me:3002/skills' to 'http://example.me:3002/skills/' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.
I don't get it why there is 'redirection' or something. This is my server side code, I granted all CORS related headers:
const express = require('express');
const app = express();
...
// CORS
app.use((req, res, next) => {
var allowedOrigins = ['http://example.me', 'http://example.me:3000', 'http://example.me:3001', 'http://example.me:3002'];
var origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
if (req.method === "OPTIONS") {
return res.status(200).end();
}
next();
});
app.use(require('./routes'));
...
app.listen(3002, () => console.log(".API Server listening on port 3002..."));
And this is client side code that using Fetch API:
fetch('http://example.com:3002/skills', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
credentials: 'include',
cache: 'no-store',
mode: 'cors'
})...
As you can see there is no redirection code. I spent almost a day to fix this issue, but everything I tried was all failed, every information that I found was useless.
I think splitting services to API Server and Web Server(actually returns HTML) was good idea, and want to go with this approach.
Is there a way to fix this problem? Any advice will very appreciate.
I solved this issue few years ago, still don't get it why it happened.
However my solution was simple, put every API into /api path.

Node + Angular: Response header isn't being passed in requests

I'm having a problem getting the cookie with my auth token to pass as part of my requests. When I look in Chrome after my authentication request is fulfilled, the response cookie is appropriately set, but it is never passed into additional requests.
Express route for /login that generates the cookie:
router.get('/login',
passport.authenticate('local', {
session: false
}),
function(req, res) {
console.log('/login authentication successful');
token.generate(req.users, function(result) {
res.cookie('access_token', result, {
//secure : true,
//maxAge : 1000*60*60, // 1 hour
path: '/',
httpOnly: true
});
res.json(Response.success(req.user));
});
}
);
I also have the following for setting the headers:
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-Credentials", true);
next();
});
Now in Angular, I am passing a config object to my $http request with withCredentials: true, but so far, nothing has worked.
$http({
method: 'GET',
url: 'http://localhost:3000/api/v1/devices',
withCredentials: true
}).then(function successCallback(response) {
// do stuff
}, function errorCallback(response) {
// oh noes!
});
A note about my setup: I have one node server running to provide the backend on port 3000, with another node server using browserSync to display the clientside on port 8080. I've seen a suggestion that using http://localhost:8080 instead of an IP could cause the cookie to not get passed, but that doesn't appear to make a difference.
Hopefully one of you fine guys or gals will have an inkling as to what my problem is. Thanks!
seem to be missing header for Access-Control-Allow-Methods which would include verbs used "OPTIONS,POST,GET,PUT,DELETE" etc
Reference MDN HTTP access control (CORS)
I don't use node a lot for cors but I know there are packages that will do all this for you

Categories

Resources