I'm doing this MeanStack course and I managed to create several files with post routes along with their schemas. But the last file I created, shopping cart schema and its route is getting blocked by cors. I tried to move the path to the files where the post works but still, get blocked, thought yesterday this workaround actually worked, but today is not working anymore. I've tried even to add an extension to chrome but nothing is working. On windows I can easily disable the cors, but not on linux
app.js
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const postsRoutes = require("./routes/posts");
const userRoutes = require("./routes/user");
const nasaRoutes = require("./routes/nasa");
const movieRoutes = require("./routes/movies");
const shoppingCartRoutes = require("./routes/shoppingCart");
const app = express();
mongoose
.connect('mongodb+srv://icenine:qN4pI8Tuy0chs7qK#mean-robot-cluster.zyjkf.mongodb.net/Mean-Robot-Cluster?retryWrites=true&w=majority'
)
.then(() => {
console.log("Connected to database!");
})
.catch(() => {
console.log("Connection failed!");
});
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-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
next();
});
app.use("/api/posts", postsRoutes);
app.use("/api/user", userRoutes);
app.use("/api/nasa", nasaRoutes);
app.use("/api/movies", movieRoutes);
app.use("api/shoppingCart", shoppingCartRoutes)
module.exports = app;
the shopping cart schema
const mongoose = require('mongoose');
const shoppingCartSchema = mongoose.Schema({
dateCrated: { type: Number, required: true },
});
module.exports = mongoose.model('ShoppingCart', shoppingCartSchema);
the route:
const express = require("express");
const ShoppingCart = require("../models/shoppingCart");
const router = express.Router();
router.post("", (req, res, next) => {
const cart = new ShoppingCart({
date:req.body.date
});
console.log(req.body)
cart.save().then(createdCart => {
res.status(201).json({
message: "Cart created successfully",
cartId: createdCart._id
});
})
.catch(err => {
res.status(500).json({
error: err
});
});
});
The Front End Angular (service)
createCart(){
let date={dateCreated: new Date().getTime()}
return this.http.post<{message:string, cartId:string}>('http://localhost:3000/api/shoppingCart', date)
}
Component
addToCart(product:Product){
let cartId = localStorage.getItem('cartId')
if(!cartId){
this.shoppingService.createCart()
.subscribe(result =>{
localStorage.setItem('cartId', result.cartId);
});
}//etc
}
The console error (front end)
The solution for Linux -Ubuntu is to open the terminal and simply type:
google-chrome --disable-web-security --user-data-dir=/tmp
You are trying to access your API which is on a different port and that's causing the cors issue, at least in the localhost environment.
you can use the cors package to allow cross-origin access.
...
const cors = require("cors");
...
app.use(cors());
...
If this is only a local project you can leave it as is or you can pass parameters to the cors function if you gonna publish your project to limit the origins allowed to access your API.
Related
I am a newbie in MEAN-Stack developing and need your help.
When I try a http get/post request using the Angular httpClient, I keep getting the following error message ERR_EMPTY_RESPONSE.
I start calling my get method within my frontend folder test.service.ts:
getTests(){
this.http
.get<{message: string, tests: TestModel[]}>('http://localhost:3000/api/test')
.subscribe((_testData)=>{
console.log(_testData);
});
}
The above used TestModel is my data model used in frontend:
export interface TestModel {
id: string;
title: string; }
Within my backend folder, my folder structure looks like in the picture attached. folder structure backend
This is how my app.js looks like (i replaced line 12, but the connection to database works).
const express = require('express')
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const test = require("./routing/test");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
mongoose
.connect(
x
)
.then(() => {
console.log("Connected to database!");
})
.catch(() => {
console.log("Connection failed!");
});
//https://www.javatpoint.com/cors-in-mean-stack
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization");
res.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS");
next();
});
app.use("/api/test", test);
module.exports = app;
My test.js where i expect the error origin looks as follows:
const express = require("express");
const testModel = require('../models/testModel');
const router = express.Router();
router.get("",(req,res,next)=>{
const testRooms = [
{
id: "1",
title: "1"
},
{
id: "2",
title:"2"
},
]
return res.json("testMessage", testRooms);
});
module.exports = router;
And finally my backend data model:
const mongoose = require('mongoose');
const express = require("express");
const router = express.Router()
const TestSchema = mongoose.Schema({
id: {type: String, required: true, unique: true},
title: {type: String, required: true},
});
module.exports = mongoose.model('TestSchema', TestSchema);
My server.js (which refers to the app.js) should work correctly, therefore I haven't posted it here.
It seems like the http module is not able to access the node backend at all, since I get the same error message if I delete the method in the "test.js". First google result hinted that this might be a CORS issue, but I don't think that this is the case here.
I am quite lost :((
If I missed to upload or mention something, just let me know.
Thanks a lot for any help and a happy new year's eve :)
I am working on my Project. When I was using Axios I ran into a few problems that I do not get.
Here I saw a similar question that represents my situation:
Node JS cookie parser not working
Here is my React Code with Axios installed and Imported:
useEffect(() => {
axios.get('http://localhost:5000/get-cookie')
.then(response => {
console.log(response.data);
})
}, [])
And my app.js code
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const Grid = require("gridfs-stream");
const cookieParser = require('cookie-parser');
const app = express();
const port = process.env.PORT || 5000;
require('dotenv').config()
//middleware
app.use(cors());
app.use(express.json());
// connecting to database
let gfs;
const uri = process.env.DB
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true });
const conn = mongoose.connection;
conn.once("open", function () {
console.log("MongoDB database connection established successfully");
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection("photos");
});
// cookie routes
app.use(cookieParser());
app.get('/set-cookie/:id', (req, res) => {
res.cookie("User_ID", req.params.id, {maxAge: 1000 * 60 * 60 * 24 * 31, httpOnly: true})
res.json("You setted the cookies")
});
app.get('/get-cookie', (req, res) => {
var cookies = req.cookies
res.json(cookies)
});
// custom routes
const notes_router = require('./routes/notes')
const avatar_router = require('./routes/avatar');
const user_router = require('./routes/user');
app.use(avatar_router);
app.use(user_router);
app.use(notes_router);
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
module.exports = gfs
I tested these on postman and they worked.
So I need help
Axios by default don't send cookies but you can pass the option withCredentials as true and it should work
useEffect(() => {
axios.get('http://localhost:5000/get-cookie',{withCredentials: true})
.then(response => {
console.log(response.data);
})
}, [])
EDIT: You will have to set the CORS policy on you Express app as well for this to work you can try the below middleware (assuming your react app is running on localhost:3000, you can change it match with you):
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
Or you can use CORS npm package as well.
I created a single page app using Angular.I'm using Node/Express on the back-end. While Express is serving my static index.html correctly.
When i try to navigation to some angular route from url address bar it saying cannot get /login...
i found this question on stackoverflow it is exactly what i am saying but its not answered yet.
Angular - Routing is not working (MEAN)
Here is my code.
var path = require("path");
var express = require("express");
var mongoose = require("mongoose");
var app = express();
require('./startups/prod')(app);
// Temp.
const TempRoutes = require("./routes/temp");
mongoose.connect('mongodb://localhost:27017/node-angular', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log("Connected to database.");
})
.catch(() => {
console.log("Connection Failed.");
});
app.use(express.json());
app.use("/", express.static(path.join(__dirname, "dist")));
app.use((request, response, next) => {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requesed-With, Content-Type, Accept,Accept-Language,Content-Language, Authorization");
response.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS");
next();
});
app.use((request, response, next) => {
response.sendFile(__dirname, path.join("dist", "index.html"))
})
module.exports = app;
I am new to node and mongoDb,
I have a mongo db account where i created a collection called "dbTestData"
I am trying to create CRUD operation using node express mongoose and express,
and i am using postman to get post update and delete values to mlab db.
My Get call is working fine, but when i try to post values in Json like,
i am getting success message , but when i check the db it is saved as
{
"_id": {
"$oid": "5c3ad1c19bc5932f800d26f7"
},
"__v": 0
}
My app.js
const express = require('express');
const bodyParser = require("body-parser");
const mongoose=require('mongoose');
const app = express();
const dbTestData=require('./models/post')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
mongoose.connect("mongodb://<userName>:<password>#ds221242.mlab.com:21242/kiitasklist").then(()=>{
console.log("hello");
}).catch(
()=>{
console.log("heee");
});
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT,DELETE, OPTIONS"
);
next();
});
app.post("/api/posts", (req, res, next) => {
const post = new dbTestData({
id:req.body.id,
name:req.body.name
});
post.save().then(documents=>{
console.log(post);
res.status(201).json({
message: 'Post added successfully'
});
});
});
app.get("/api/posts",(req,res,next)=>{
dbTestData.find().then(documents=>{
res.status(200).json({
message:'Posts fetched successful',
posts:documents
});
});
});
app.put("/api/posts/:id",(req,res,next)=>{
const post = new dbTestData({
_id:req.body._id,
name:req.body.name
});
dbTestData.updateOne({_id:req.params.id},post).then(result=>{
res.status(200).json({message:"update successfully"});
});
});
app.delete("/api/posts/:id",(req,res,next)=>{
dbTestData.deleteOne({_id:req.params.id}).then(documents=>{
res.status(200).json({
message:'posts fetched successful',
posts:documents
});
});
});
module.exports = app;
My Server.js
const http = require('http');
const app = require('./api/app');
const port = process.env.PORT || 3000;
const server = http.createServer(app);
server.listen(port);
My post.js where i have created the mongoose schema
const mongoose=require('mongoose');
var Schema = mongoose.Schema;
module.exports= mongoose.model("dbTestData", new Schema({}), "DbTestData");
both the get and delete works ,
But the post and put is not happening properly, it returns a success message in my console but empty value like
{
"_id": {
"$oid": "5c3ad1c19bc5932f800d26f7"
},
"__v": 0
}
is saved during POST and nothing happens during PUT.
To solve this post issue
var Schema = mongoose.Schema;
PostSchema = new Schema({
id:Number,
name: String
});
// the compile the model using mongoos model function giving the schema u created
const Post = module.exports= mongoose.model("dbTestData", PostSchema, "DbTestData");
after that in your post req do it like this
//before posting you need to require the model first
const Post = require('./models/post'); // your post.js
app.Post("/api/posts", (req, res, next) => {
const post = new Post({
id:req.body.id,
name:req.body.name
});
post.save().then(documents=>{
console.log(post);
res.status(201).json({
message: 'Post added successfully'
});
});
});
make sure you create/define your schema correctly in order to save data using it.
after that put is the same the way u did it should work fine after u define your schema correctly
and finally try this also. make sure you add these tow line the exact same way I have given in your case you have made them switched
// Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
I have created a simple server in node js to take the request from a react app.
But for the GET method there is no CORS error but whenever I do post, it gives me an error.
For the POST method to work, I have implemented in index.js file of the actions folder and it should hit the url from the server.js file.
index.js
import axios from 'axios';
export const GET_NAVBAR = "GET_NAVBAR";
export const LOGIN = "LOGIN";
export const BASE_API_URL = "http://localhost:3030";
export const GUEST_API_URL = "https://XXX.XXX.XXX.X:5443/wcs/resources/store/1";
export const getNavbar = () => {
return axios.get(BASE_API_URL + '/topCategory').then(res => {
return {
type: GET_NAVBAR,
payload: res.data.express.catalogGroupView
};
});
};
export const login = () => {
return axios.post(GUEST_API_URL + '/guestidentity', {}).then(res => {
console.log(res);
return {
type: LOGIN,
payload: {}
}
}).catch(e => {
console.log(e);
return {
type: LOGIN,
payload: {}
}
});
};
server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const Client = require('node-rest-client').Client;//import it here
const app = express();
const helmet = require('helmet');
const morgan = require('morgan');
// enhance your app security with Helmet
app.use(helmet());
// use bodyParser to parse application/json content-type
app.use(bodyParser.json());
app.use(cors());
// log HTTP requests
app.use(morgan('combined'));
app.post('/guestidentity', (req, res) => {
var client = new Client();
// direct way
client.post("https://XXX.XXX.XXX.X:5443/wcs/resources/store/1/guestidentity", (data, response) => {
res.send({express: data});
});
});
const port = 3030;
app.listen(port, () => console.log(`Server running on port ${port}`));
I don't know where my code is getting wrong. Can anybody please help me to troubleshoot this issue. I would be grateful if someone could provide an insight or guide me a little. Thanks
For my part I used
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();
});
It will accept from any * sources, you might want to change that later
In your server.js , add the following middleware.
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3030/');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
};
app.use(allowCrossDomain);