I am making a web app and have made back-end with express, mongodb and node.js, while the frontend is made in React.js.
The backend runs completely fine on its own, when run using "nodemon server.js"
But when connected to frontend using axios, it throws "Network Error" error.
Here is my code to server.js (back-end, connecting url) and http-common.js (front-end, axios)
server.js
import cors from "cors";
import userquery from "./student/api/query.routes.js";
import admin from "./admin/api/admin.routes.js";
const app = express();
app.use(cors());
app.use(express.json());
app.use("/api/v1/user", userquery);
app.use("/api/v1/admin", admin);
app.use("*", (req, res) => {
res.status(404).json({ error: "not found" });
});
export default app;
query.routes.js
import QueryCtrl from "./query.controller.js";
import personalQueriesCtrl from "./personalQueries.controller.js";
import SubjectCtrl from "./subject.controller.js";
import UserCtrl from "./user.controller.js";
const router = express.Router(); //creates routes people can go to
router.route("/").get(QueryCtrl.apiGetQueries);
router.route("/signup").post(UserCtrl.apiPostUser);
router.route("/subjects").get(SubjectCtrl.apiGetSubjects);
router.route("/AskQuery").post(personalQueriesCtrl.apiPostQuery);
export default router;
http-common.js
export default axios.create({
baseURL: "http://localhost:5000/api/v1/user/",
headers: {
"Content-type": "application/json",
},
proxy: false,
});
Please help if you can!
Related
I was using the following code within my Flutter app and it was working with no problems, but today after I upgraded my Flutter, it doesn't work and gives me XMLHttpRequest error.
Future<void> _authenticate(
String email, String password, String urlSegment) async {
final host = UniversalPlatform.isAndroid ? '10.0.2.2' : '127.0.0.1';
final url = Uri.parse('http://$host:8000/api/$urlSegment');
try {
final http.Response response = await http.post(
url,
headers: {"Content-Type": "application/json"},
body: json.encode(
{
'email': email,
'password': password,
},
),
);
Does anything have been changed in new Flutter version? Should I change the following line of code that specifies my host address?
final host = UniversalPlatform.isAndroid ? '10.0.2.2' : '127.0.0.1';
EDIT: I tried to add cors to my NodeJS backend server and this is my app.ts file as following:
import express, { Request, Response, NextFunction } from "express";
import cors from "cors";
import dotenv from "dotenv";
dotenv.config();
import config from "config";
import responseTime from "response-time";
import connect from "./utils/connect";
import logger from "./utils/logger";
import routes from "./routes";
import deserializeUser from "./middleware/deserializeUser";
import { restResponseTimeHistogram, startMetricsServer } from "./utils/metrics";
import swaggerDocs from "./utils/swagger";
const allowedOrigins = ['http://localhost:8000' , 'https://10.0.2.2:8000', 'http://127.0.0.1:8000'];
const options: cors.CorsOptions = {
origin: allowedOrigins
};
const port = config.get<number>("port");
const app = express();
app.use(express.json());
app.use(cors(options));
app.use(deserializeUser);
app.use(
responseTime((req: Request, res: Response, time: number) => {
if (req?.route?.path) {
restResponseTimeHistogram.observe(
{
method: req.method,
route: req.route.path,
status_code: res.statusCode,
},
time * 1000
);
}
})
);
app.listen(port, async () => {
logger.info(`App is running at http://localhost:${port}`);
await connect();
routes(app);
startMetricsServer();
swaggerDocs(app, port);
});
But still doesn't work and I get the same error!
You've set the allowed origins to :8000, but that's the backend server's address. Instead, you need to set it to the Flutter debug server's address (and eventually to the web server where you host the production app, if that's not exactly the same as the backend server). (You can remove all the addresses ending in 8000.)
The problem is that the debug server picks a random port for each run. You can tell it to use a fixed port and then that becomes the port you need to include in your allowed origins.
Add --web-hostname=localhost --web-port=9999 as command line parameters to where you run your main.dart, then add localhost:9999 as an allowed origin.
(As a get-out-of-jail, also try * as an allowed origin.)
Finally, you should probably explicitly set the CORS allowed methods to the list of methods your server's API expects; probably OPTIONS, GET and POST.
I have deployed a react-app to AWS S3 and a node/express API in heroku but Iam not able to connect them together event with the cors config in the API or proxy in the react-app
I can't find to make this correct.
frontend package.json
"name": "frontend",
"proxy": "https://planet-api-test.herokuapp.com/",
"version": "0.1.0",
"private": true,
app.js
const [message, setMessage] = useState('')
useEffect(() => {
const myFunction = async () => {
const { data } = await axios.get('/api/users')
setMessage(data)
}
myFunction()
})
server.js
import express from 'express'
import cors from 'cors'
import userRoutes from './routes/userRoutes.js'
const app = express()
const port = process.env.PORT || 5000
app.use(express.json())
app.use(cors())
app.use('/api/users', userRoutes)
error in console
for some reason your app tries to send the request to http instead of https try to hard-code it inside the axios.get see what happens
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.
I have a troubles with express.js it's trying to use ssl3 but I didn't use it anywhere. I see next error then running the server:
(node:7920) [DEP0026] DeprecationWarning: util.print is deprecated.
Use console.log instead. Error: 4776:error:1408F10B:SSL
routines:ssl3_get_record:wrong version
number:openssl\ssl\record\ssl3_record.c:252:
The server.js file looks like this:
// import npm modules
import fs from 'fs';
import path from 'path';
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import winston from 'winston';
import compression from 'compression';
import expressWinston from 'express-winston';
import winstonPapertrail from 'winston-papertrail';
import jwt from 'express-jwt';
import http from 'http';
// import custom configuration and utilities
import config from './config';
import logger from './utils/logger';
import db from './utils/db';
import routes from './routes';
// initialize the api
const api = express();
// initialize middleware
api.use(cors());
api.use(compression());
api.use(bodyParser.urlencoded({ extended: true }));
api.use(bodyParser.json());
// ignore authentication on the following routes
api.use(
jwt({ secret: config.jwt.secret }).unless({
path: [
'/',
'/auth/signup',
'/auth/login',
'/auth/forgot-password',
'/auth/reset-password',
],
}),
);
// throw an error if a jwt is not passed in the request
api.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
res.status(401).send('Missing authentication credentials.');
}
});
// initialize our logger (in our case, winston + papertrail)
api.use(
expressWinston.logger({
transports: [
new winston.transports.Papertrail({
host: config.logger.host,
port: config.logger.port,
level: 'error',
}),
],
meta: true,
}),
);
// listen on the designated port found in the configuration
api.listen(config.server.port, err => {
if (err) {
logger.error(err);
process.exit(1);
}
// require the database library (which instantiates a connection to mongodb)
db();
// loop through all routes and dynamically require them – passing api
Object.entries(routes).forEach(([ key, route ]) => {
route(api);
});
// output the status of the api in the terminal
logger.info(`API is now running on port ${config.server.port} in ${config.env} mode`);
});
export default api;
├───dist
└───src
├───config
├───controllers
├───models
├───routes
└───utils
How can I solve this problem? I wont use ssl right now. Thanks
Been working fine up until this morning and now, suddenly i am getting a type error stating that Cors is not a function
My code
import * as Cors from "cors";
...
const corsOptions: Cors.CorsOptions = {
allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept", "X-Access-Token", "Authorization"],
credentials: true,
methods: "GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE",
origin: "*",
preflightContinue: true
};
createConnection(ormConfig).then(async connection => {
// run pending migrations
await connection.runMigrations();
// create express server
const app = express();
app.use(bodyParser.json({limit: "50mb"}));
app.use(bodyParser.urlencoded({limit: "50mb", extended: true}));
// register cors
app.use(Cors(corsOptions)); //<---error occurs here
// register all controllers
useExpressServer(app, {
routePrefix: "/api",
controllers: [
__dirname + "/controllers/**/*{.js,.ts}"
],
authorizationChecker: async (action: any, roles: string[]) => {
return JwtAuthorizationMiddleware.checkIsAuthorized(action, roles);
},
currentUserChecker: async (actions: any) => {
return JwtAuthorizationMiddleware.extractUserFromJwtToken(actions);
}
});
// start the express server
const port: number = +(process.env.PORT || 44320);
app.listen(port, (err: Error) => {
console.log(`App listening on port ${port}`);
console.log("Press Ctrl+C to quit.");
});
}).catch(error => console.error("TypeORM connection error: ", error));
Current versions of cors and Node
cors: "^2.8.4"
Node: v8.4.0
The only change that recently done was on Friday when I included the following packages
multer: "^1.3.0"
#google-cloud/datastore: "^1.1.0"
#google-cloud/storage: "^1.4.0"
and everything was working till this morning, same version is deployed on gcloud and this works so I am a little bemused as to why I Am suddenly getting this error and what could be the cause.
Any help is greatly appreciated
You have to have something such as
const cors = require('cors');
in the top of your file, and then refer to the module as cors, not Cors.
You can read Express's cors documentation to learn more.
To apply cors to all routes in your project you can write:
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
Ok, so I found the problem which turned out to be PEBKAC.
While implementing file uploads and storage in gcloud, I had to enable CORS on gcloud and had saved the settings file in the root of my project, this file was called cors.json.
In the code posted in my question above the import statement was reading my cors.json file and not (as I thought) the cors NPM package.
Lesson learnt from this one should anyone else make the same rookie mistake I just made is be careful what you name your files and where you put them!!!