How to stop NodeJS/Express from caching mongodb query results - node.js

It seems my Node JS or Express is caching the results from MongoDB, this seems to be an advantage for some, but for me it is causing a problem. I don't want the json response to be cached. Please suggest how to stop this.
This is my Server.js if you notice I have used res.headers and app.disable methods to prevent caching.
// set up ======================================================================
var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var app = express();
var server = require('http').Server(app);
var mongoose = require('mongoose'); // mongoose for mongodb
var port = process.env.PORT || 8000; // set the port
var database = require('./config/database'); // load the database config
var morgan = require('morgan');
var methodOverride = require('method-override');
var io = require('socket.io')(server);
var cors = require('cors');
var messageId = {};
// configuration ===============================================================
// Connect to DB
mongoose.connect(database.remoteUrl)
mongoose.Promise = global.Promise;
mongoose.connection.on('error', function(e) {
console.log('Can not connect Error:>>',e);
process.exit();
});
mongoose.connection.once('open', function(d) {
console.log("Successfully connected to the database");
})
//app.use(express.static('./public')); // set the static files location /public/img will be /img for users
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.urlencoded({'extended': 'true'})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({type: 'application/vnd.api+json'})); // parse application/vnd.api+json as json
app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request
app.use(bodyParser.urlencoded({extended:true}))
app.use(bodyParser.json())
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'DELETE, PUT');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Cache-Control", "no-cache, no-store, must-revalidate");
res.header("Pragma", "no-cache");
res.header("Expires", 0);
next();
});
app.disable('view cache');
io.set('origins', '*:*');
http = require('http'),
server = http.createServer(function (req, res) {
//res.writeHead(200,{'content-type':'text/plain'});
// res.write("Sever On");
// res.end();
}),
io = io.listen(server);
io.on('connection', function (socket) {
console.log('User Connected -- Server Online');
socket.on('message', function (msg,msgId) {
io.emit('message', "Hello");
console.log("message from client:", msg);
setInterval(function(){
io.emit("messageStatus",msgId);
},500)
});
});
app.use(require('./app/routes.js'));
app.listen(port);
//server.listen(port);
console.log("App listening on port " + port);
This is my Route.js
var express = require('express')
var app = module.exports = express.Router();
var UserProfile = require('./models/UserProfile');
app.get('/User', function (req, res) {
UserProfile.find({
EmailID: req.query.EmailID
}, function (err, profile) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err) {
return res.json({
"success": false,
"msg": err
})
console.log(err);
}
res.status(200).send(profile)
});
});
This is my provider.js
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class ProfileProvider {
data : any
constructor(public http: Http,) {
}
// public getProfile(EmailID){
// console.log(this.http.get(CONFIG.apiUrl+'User?EmailID='+EmailID).map(response => response.json().result));
// return this.http.get(CONFIG.apiUrl+'User?EmailID='+EmailID).map(response => response.json().result);
// }
public getProfile(EmailID){
console.log("Provider,>>",EmailID)
if (this.data) {
return Promise.resolve(this.data); }
return new Promise(resolve => {
this.http.get('http://192.168.0.100:8000/User?EmailID='+EmailID)
.map(res => res.json())
.subscribe(data => {
this.data = data;
resolve(this.data);
});
});
}
}
Now if run this (http://192.168.0.100:8000/User?EmailID=abc#abc.com) on my browser and if I change the email ID, i get different responses. But in the ionic app it some how gives me the same responses even after changing the parameters
And I am using AWS and my MongoDB is hosted there.

Your problem is in the provider. You are caching the results of the api call in the data property.
if (this.data) {
return Promise.resolve(this.data); }
Try always fetching the data:
public getProfile(EmailID){
return new Promise(resolve => {
this.http.get('http://192.168.0.100:8000/User?EmailID='+EmailID)
.map(res => res.json())
.subscribe(data => {
resolve(data);
});
});
}

Related

Am I doing anything wrong here node+express + vue SPA getCSRFTOKEN()

My index.js Server
// USE STRICT;
const express = require('express');
const app = express();
const session = require('express-session');
const http = require('http').Server(app);
const socket = require('socket.io');
const schedule = require('node-schedule');
const cors = require('cors');
const io = socket(http, {
cors: {
origin: 'http://localhost:8080',
methods: ['GET', 'POST'],
allowedHeaders: ['my-custom-header'],
credentials: true
}
});
const port = 8080;
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/uploads'));
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const mustacheExpress = require('mustache-express');
app.engine('html', mustacheExpress());
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
const secret = 'somesecretkeyhere';
const passport = require('passport');
const helmet = require('helmet');
const { sendMail } = require('./controllers/sellerAdsController');
// Gives us access to variables set in the .env file via `process.env.VARIABLE_NAME` syntax
// require('dotenv').config();
// Must first load the models before passport
require('./models/user');
// Pass the global passport object into the configuration function
require('./config/passport')(passport);
// This will initialize the passport object on every request
app.use(passport.initialize());
// Allows our remote applications to make HTTP requests to Express application
app.use(cors());
app.use(helmet());
app.use(express.urlencoded({ extended: false }));
// app.use(express.json()); //WARNING: Do not turn on. stops formidable for api calls
app.use(cookieParser(secret));
app.use(session({
secret: secret,
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: true,
secure: true
}
}));
app.use(csrf());
// Stop page caching
app.use(function (req, res, next) {
res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0');
next();
});
// Imports all of the routes from ./routes/index.js
app.use(require('./routes/api/v1'));
// Socket Operations
// io.on('connection', io => {
// let sessionId = io.id;
// io.on('clientHandshake', (data) => {
// console.log(data);
// io.emit('serverHandshake', { sessionId: sessionId });
// });
// });
// io.use((socket, next) => {
// const username = socket.handshake.auth.username;
// if (!username) {
// return next(new Error('invalid username'));
// }
// console.log(username);
// socket.username = username;
// next();
// });
io.on('connection', (socket) => {
console.log('👾 New socket connected! >>', socket.id);
// notify existing users
socket.broadcast.emit('user connected', {
userID: socket.id,
username: socket.username,
});
socket.on('private message', ({ content, to }) => {
socket.to(to).emit('private message', {
content,
from: socket.id,
});
console.log(content, to);
});
});
// EROOR HANDLING ROUTES MUST BE BENEATH ALL APP.USE AND ROUTES
// Check if request is from web or app (HTML/JSON)
// Handle 404
app.use(function (req, res) {
res.status(404);
res.render('404.html', { title: '404: File Not Found' });
});
// Handle 500
app.use(function (error, req, res) {
return res.send(error);
// res.status(500);
// res.render('500.html', { title: '500: Internal Server Error', error: error });
});
// SCHEDULED JOBS
const now = new Date();
let date = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 0, 0);
schedule.scheduleJob(date, sendMail);
http.listen(port, () => {
console.log(`listening on *:${port}`);
});
And this is how I am getting from VUE
window.axios.get('/databank/getCSRF').then((response) => {
window.axios.defaults.headers.common['XSRF-TOKEN'] = response.data;
}, (err) => {
console.log(err)
})
And this is my login request header
XSRF-TOKEN from my login request header sent by axios
So Ive set my server up like that, and my vue SPA, but getCSRF() seems to be getting the request but I can't do a POST request back to the server throws an error
ForbiddenError: invalid csrf token
at csrf
Maybe because you wrote XSRF-TOKEN instead of CSRF-Token as it suggests in the Express Documentation.

Cors request did not succeed when im trying to run it on another pc

so im developing website using nodejs, and then deploying it to microsoft azure, and using Azure Database for mysql server to be exact, and importing my databse using mysql workbench, now the problem is in the CORS, everyhting going well i run it on chrome and firefox in the same pc works fine, but when i try to acces the website using another pc, i get the error says "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3000/data/price%20asc. (Reason: CORS request did not succeed)".
heres my nodejs code:
//use path module
const path = require("path");
//use express module
const express = require("express");
//use hbs view engine
// const hbs = require('hbs');
//use bodyParser middleware
const bodyParser = require("body-parser");
//use mysql database
const mysql = require("mysql");
const app = express();
const db = require("./database");
//cors
const cors = require("cors");
// app.use(cors());
// app.use(
// cors({
// origin: "*",
// })
// );
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();
});
//konfigurasi koneksi
const conn = mysql.createConnection({
// host: 'localhost',
// user: 'root',
// password: '',
// database: 'domdom'
host: "domdom.mysql.database.azure.com",
user: "domdom#domdom",
password: "Banana123",
database: "schema1",
port: 3306,
ssl: true,
});
//connect ke database
conn.connect((err) => {
if (err) throw err;
console.log("Mysql Connected...");
});
//set views file
app.set("views", path.join(__dirname, "/"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.json());
app.use(express.static(__dirname));
app.param("productname", function (request, response, next, product) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.product = product;
return next();
});
app.param("sort", function (request, response, next, price) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.price = price;
return next();
});
app.param("id", function (request, response, next, id) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.id = id;
ß;
return next();
});
//get all data
app.get("/data/:sort", (req, res) => {
let sql = "SELECT * FROM products Order By " + req.price;
let query = conn.query(sql, (err, results) => {
res.json(results);
});
});
//untuk search and sort
app.get("/data/:productname/:sort", function (req, res) {
let sql =
"SELECT * FROM products WHERE name like '%" +
req.product +
"%' Order By " +
req.price;
let query = conn.query(sql, (err, results) => {
res.json(results);
});
});
//untuk save data
app.post("/save/:id", (req, res) => {
let sql =
"INSERT INTO cart SELECT * from products WHERE id = '" + req.id + "'";
let query = conn.query(sql, (err, results) => {
if (err) throw err;
res.redirect("/");
});
});
//render interface
app.get("/", (req, res) => {
res.render("index");
});
//server listening
app.listen(3000, () => {
console.log("Server is running at port 3000");
});
as you can see in the code i have tried 3 ways trying to solve this problem, but nothing works, please help.
If you are using Azure app service to host your nodejs app,the most fastest way to config CORS on Azure Portal => app service => CORS :
I did some test on my side and this is my nodejs server code(as you can see, no config for CORS) :
const express = require('express')
const app = express()
const port = process.env.PORT || 8080
app.use(express.json())
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.post('/', (req, res) => {
var body = req.body;
res.send(`Hello ${body.name}!`)
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Test HTTP request from an local static web page:
<!DOCTYPE html>
<html>
<body>
<h1>The XMLHttpRequest Object</h1>
<button type="button" onclick="loadDoc()">Request data</button>
<p id="demo"></p>
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("POST", "https://nodeweb05.azurewebsites.net/", true);
xhttp.setRequestHeader("Content-type", "application/json");
var body = {"name":"testuser"};
xhttp.send(JSON.stringify(body));
}
</script>
</body>
</html>
You can try it yourself.
If you want to config CORS on code level, just try the config below:
const express = require('express')
const app = express()
var cors = require('cors')
app.use(cors())

Getting error Response with status: 404 Not Found for URL

I am facing an issue while running the angular and nodejs app which I am trying to integrate with Neo4j app. The issues are the errors that I get-
POST http://localhost:7474/viewNodesStart 404 (Not Found)
and
EXCEPTION: Response with status: 404 Not Found for URL:
http://localhost:7474/viewNodesStart
Though this topic is repetitive in StackOverflow , I am still posting it because the following links suggestions didn't suit my issue.
Angular2 404 Not Found for URL: http://localhost/WebApi2/api/hero
EXCEPTION: Response with status: 404 Not Found for URL / Angular2
https://github.com/johnpapa/angular-tour-of-heroes/issues/94
Please check my code
app.component.ts
import { Component, OnInit } from '#angular/core';
import { Injectable } from '#angular/core';
import { ToasterService } from '../toaster.service';
import { FormGroup, FormControl, FormBuilder, Validators } from '#angular/forms';
import { Http, Response, Headers } from '#angular/http';
import { config } from '../config';
import { Subject } from 'rxjs';
import 'rxjs/add/operator/map';
import { map } from 'rxjs/operators';
import 'rxjs/Rx';
import { Observable } from 'rxjs';
// Statics
import 'rxjs/add/observable/throw';
#Component({
selector: 'app-neo4j-primary',
templateUrl: './neo4j-primary.component.html',
styleUrls: ['./neo4j-primary.component.css']
})
export class Neo4jPrimaryComponent implements OnInit {
constructor(private http: Http, private notify: ToasterService) { }
ngOnInit() {
this.viewNodesStart();
}
emptyObj;
info;
// ------------------------------- Nodes Entire Data --------------
viewNodesStart() {
console.log("INSIDE viewNodesStart()")
// Nodes Value
console.log("inside Nodes Value");
var data = localStorage.getItem('token');
console.log("data is=>",data);
var url = config.url;
var port = config.port;
this.http.post("http://"+url+":"+port+"/viewNodesStart",this.emptyObj)
.map(Response => Response.json())
.subscribe((res: Response) => {
console.log("XXXXXXXXXXXX Response on /viewNodesStart", res);
this.info = res;
console.log('success', this.info.statusCode);
if (this.info.statusCode == 200) {
this.notify.Success("Data added successfully");
} else {
this.notify.Error("Data is not inserted")
}
});
}
}
server.js
var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
const neo4j = require('neo4j-driver').v1;
var app = express();
var restify = require('restify');
var expressJwt = require('express-jwt');
var session = require('express-session');
var config = require('./config.json')
app.use(restify.plugins.bodyParser());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(bodyParser.json({
type: 'application/vnd.api+json'
}))
app.use(cors());
app.use(session({
secret: config.secret,
resave: false,
saveUninitialized: true
}));
//*****TM Server ******/
app.use('/viewNodesStart', require('./neo4jserver/tmserver'));
app.get('/', function(req, res) {
res.send('Welcome');
console.log("welcome in console");
});
// start server
var server = app.listen(7473, function() {
console.log('Server listening at http://' + server.address().address + ':' + server.address().port);
});
nodeserver.js
// Require Neo4j
var neo4j = require('neo4j-driver').v1;
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var express = require('express');
var router = express.Router();
var app = express();
// Create Driver
const driver = new neo4j.driver("bolt://localhost:11001",neo4j.auth.basic("neo4j", "abc"));
// Run Cypher query
const cypher = 'MATCH (n) RETURN count(n) as count';
//View Engine
app.set('views', path.join(__dirname, 'views'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(express.static(path.join(__dirname, 'public')));
var session = driver.session();
app.post('/', function(req, res) {
console.log("INSIDE NODE JS CONTROLLER OF viewNodesStart");
console.log("BODY IS ", req.body);
var log = JSON.parse(req.body);
console.log(log);
session.run('MATCH (n) RETURN n LIMIT 25').then(function(result) {
result.records.forEach(function(record) {
console.log("record", record);
console.log("result = ", result)
console.log("record._fields[0].properties", record._fields[0].properties);
res.status(200).send({
statusCode: '200',
result: result
});
});
}).catch(function(err) {
console.log(err);
}).then(res=>{
console.log("res.records.length", res.records.length);
}
)
res.send('It Works');
res.send(result);
});
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === "OPTIONS")
res.send(200);
else
next();
}
console.log('Server started on port 11005');
module.exports = router;
module.exports = app;
I guess the problem is with the url you are passing to the http request. You are passing the path of the anuglar route and want to call the node api.
Change the url there to the nodeapi url. Then it will work.

Angular 4 file upload with other post data giving empty object on server side (node js)

I am stuck with a problem from last 3 hours, I was trying to upload file and other post data to the server side, I am using angular for frontend part and node for server side.
This is my component.ts code
save(data) {
console.log(data);
const files: Array<File> = this.filesToUpload;
console.log(files);
for(let i = 0; i < files.length; i++){
this.formData.append("image[]", files[i], files[i]['name']);
}
//trying to send some dummy entry but no luck
this.formData.append('title','dasdasdas');
// console.log(this.formData.getAll('image'));
// console.log('form data variable : '+
this.formData.toString());
// console.log(this.formData.getAll('image[]'));
this.restApi.addRecipe(this.formData).subscribe(res =>
{
console.log(res);
});
This is my angular service code:
addRecipe(data){
console.log(this.baseUrl);
const headers = new Headers({});
let options = new RequestOptions({ headers });
return this.http.post(this.baseUrl+'addRecipe',data,options).map(res=>res.json());
}
This is my server.js code:
const express = require('express');
const mongoose = require('mongoose');
const admin = require('./routes/admin');
const path = require('path');
const app = express();
const config = require('./config/config');
const bodyParser = require('body-parser');
const cors = require('cors');
mongoose.Promise = global.Promise;
mongoose.connect(config.database, (err) => {
if (err) {
console.log(err);
} else {
console.log('connected')
}
})
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'client/dist')));
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'DELETE, PUT');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
//admin route
app.use('/admin', admin);
app.listen(3000, (err) => {
if (err) console.log("err");
console.log("port started");
})
This is the controller code where I have written the logic of inserting:
module.exports.addRecipe = (req, res) => {
const body = req.body
console.log(body);
return;
...
}
whenever I console.log(body), I am getting a empty object {}, from the angular side I have tried changing the content type but nothing seems to be working, I am new to node and angular and I searched a lot about this problem but no solution seems to be working.

Configuring Sequelize with Azure SQL DB (express/node)

I'm prety new to nodejs and even more so Sequelize. I'm trying to setup an API to MSSQL using Sequelize but some of the basics are eluding me. I just can't seem to interact with my SQL DB.
This is my server.js file
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var models = require('./models');
var port = process.env.PORT || 3011;
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
var transactionRouter = require('./server/Routes/transactionRoutes')();
var userRouter = require('./server/Routes/userRoutes')();
var authRouter = require('./server/Routes/authRoutes')();
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8012');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', false);
// Pass to next layer of middleware
next();
});
app.use('/api/transactions', transactionRouter);
app.use('/api/auth', authRouter);
app.use('/api/users', userRouter);
app.get('/', function(req, res) {
res.send('welcome to my API');
});
app.listen(port, function() {
console.log('Gulp is running my app on PORT: ' + port);
});
module.exports = app;
Models/Index.js
var fs = require("fs");
var path = require("path");
var Sequelize = require("sequelize");
var env = process.env.NODE_ENV || "development";
var sequelize = new Sequelize('dbname', 'dbusername', 'dbpassword', {
host: 'dbhostname',
dialect: 'mssql',
pool: {
max: 5,
min: 0,
idle: 10000
}
});
var db = {};
fs
.readdirSync(__dirname)
.filter(function(file) {
return (file.indexOf(".") !== 0) && (file !== "index.js");
})
.forEach(function(file) {
var model = sequelize["import"](path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if ("associate" in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
A model Models/user.js
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('BO_Users', {
username : DataTypes.STRING,
password : DataTypes.STRING,
});
return User;
};
A the routes server/Routes/userRoutes.js
var express = require('express');
var models = require('../../models');
var routes = function() {
var userRouter = express.Router();
userRouter.route('/')
.get(function(req, res) {
console.log("Made it to the new route");
console.log("made it to the new get route");
models.User.findAll({})
.then(function() {
console.log('Got some users');
});
})
.post(function(req, res) {
console.log("Made it to the post route");
});
return userRouter;
};
module.exports = routes;
I'm pretty sure I need to do a models.sequelize.sync() somewhere, but I'm kinda lost and having trouble finding a good tutorial that gets through to me. I have the tables in place, I just want to start interacting with them. Thanks!!
As a quick fix, I would suggest putting the .sync() in server.js just prior to and wrapping the listener so that the app cannot be interacted with before the DB is ready.
For example:
models.sequelize.sync().then(function() {
console.log('starting listener on PORT: '+port);
app.listen(port, function(err) {
if(err) return console.error('Failed to start listener: '+err);
console.log('Gulp is running my app on PORT: ' + port);
});
}).catch(function(err) {
console.error('failed to sync DB: '+err);
});

Resources