I have a client app that is connected to a server app in node.js, I already set the allow origin before setting the routes, but it still gives me the cross-origin issue.
So I have the angular app that calls the service like this:
app.service
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import 'rxjs/add/operator/map';
// import * as config from '../../../../config.json';
#Injectable()
export class PDFService {
constructor (private http: Http) {}
generatePDF() {
return this.http.get("localhost:8000/pdfURL")
.map((res:Response) => res.json());
}
}
app.component
import { Component } from '#angular/core';
import { PDFService } from './app.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
constructor(private pdfService: PDFService) {
}
generatePDF() {
this.pdfService.generatePDF().subscribe(
(response) => {
console.log("pdf generated");
},
(error) => {
console.log("something went wrong on generating pdf");
}
);
}
}
the function above is called with a simple button clicked.
On the server side, my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var router = express.Router();
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
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();
});
app.use('/',require('./routes/index'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
the app.use after the allow origin calls the routing initialize:
var express = require('express');
var router = express.Router();
router.use('/',require('./pdfGenerator'))
router.use(function(req,res,next){
return res.status(404).json({Error:"Invalid Url"});
})
module.exports = router;
and finally there i call the pdfGenerator router:
var express = require('express');
var router = express.Router();
var pdfGenerator = require('../controllers/pdfGenerator');
router.get('/pdfURL', pdfGenerator.pdfToUrl);
module.exports = router;
that calls the controller:
var express = require('express');
var router = express.Router();
var fs = require('fs');
var pdf = require('html-pdf');
//var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };
module.exports = {
pdfToUrl: function(req,res,next) {
console.log("adas");
pdf.create('<div style="background-color:blue">a simple text</div>', options).toFile('./businesscard.pdf', function(err, res) {
console.log("asd"); // { filename: '/app/businesscard.pdf' }
if (err) return console.log(err);
console.log("asd"); // { filename: '/app/businesscard.pdf' }
});
}
};
I tried with postman and it worked well any tip?
Try install Cors: https://www.npmjs.com/package/cors
and use it like this:
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
You can also of course use a plugin. For example in chrome: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en
Hope this helps ;)
Related
My router does not seem to work on remote server but it works perfects on local server.
I've tried with so many methods to solve it but yet no results.
At first, the error that gave me had something to do with phusion, hence if the if statement in app.js and now it gives no error in log, but on browser it shows: cannot get /
Please help me solve, code snippets below:
app.js
const http = require('http');
const app = require('./app')
if (typeof(PhusionPassenger) != 'undefined') {
PhusionPassenger.configure({ autoInstall: false });
}
const port = process.env.PORT || 9100;
const server = http.createServer(app);
server.listen(port, ()=>console.log(`Server running on port ${port}`));
index.js
if (process.env.ENV !== "development") {
require('dotenv').config();
}
// console.log(process.env)
const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const helmet = require('helmet');
// Routes imports
const admin_users = require('./routes/admin/users');
const admin_locations = require('./routes/admin/locations');
// const admin_products = require('./routes/admin/products');
const admin_deliveries = require('./routes/admin/deliveries');
const admin_payments = require('./routes/admin/payments');
const admin_dashboard = require('./routes/admin/dashboard');
const admin_orders = require('./routes/admin/orders');
const users = require('./routes/users');
const products = require('./routes/products');
const deliveries = require('./routes/deliveries');
const payments = require('./routes/payments');
const tickets = require('./routes/tickets');
// const files = require('./routes/files');
const cards = require('./routes/cards');
let app = express();
app.set('trust proxy', true);
app.use(helmet());
// app.use(express.staticProvider(__dirname + '/public'));
// view engine setup
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE, PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Access-User, X-Access-Token,Authorization");
// next();
if ('OPTIONS' === req.method) {
//respond with 200
return res.status(200).json({});
// next();
}
else {
//move on
next();
}
});
// Routes
app.get('/', (req,res,next)=>{
res.send('server is up and running');
})
app.use('/admin/users', admin_users);
app.use('/admin/locations', admin_locations);
// app.use('/admin/products', admin_products);
app.use('/admin/deliveries', admin_deliveries);
app.use('/admin/payments', admin_payments);
app.use('/admin/orders', admin_orders);
app.use('/dashboard', admin_dashboard);
app.use('/users', users);
app.use('/products', products);
app.use('/deliveries', deliveries);
app.use('/payments', payments);
app.use('/tickets', tickets);
// app.use('/files', files);
app.use('/cards', cards);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
require("./scheduler")
// catch 404 and forward to error handler
app.use(function(req, res, next) {
let err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
require('./server');
module.exports = app;
You should remove this code below
app.get('/', (req,res,next)=>{
res.send('server is up and running');
})
and replace it with
app.get('/', (req,res,next)=>{
res.send('server is up and running');
})
Place it below
app.set('view engine', 'ejs')
I'm working on a project that uses ReactJS typescript for the front-end, express for the back-end, and MongoDB for the database.
The main issue I am having is that I want to somehow send data from my React component to the express app so that it can query and add things to the database.
Currently, I have the express server running on http://localhost:9000, and the React app on http://localhost:3000, and I can connect them using routes.
My express app looks like the following:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var testAPIRouter = require('./routes/testAPI');
var testAddUser = require('./routes/addUser');
const MongoClient = require('mongodb').MongoClient;
const mongoose = require('mongoose');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use("/testAPI", testAPIRouter);
app.use("/addUser", testAddUser);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
const dbRoute = 'mongodb+srv://Adminname:fjfeinjd#pawornaw-b4vzg.gcp.mongodb.net/test?retryWrites=true&w=majority';
mongoose.connect(dbRoute,
{useNewUrlParser: true})
.then(() => console.log("Connected to MongoDB"))
.catch(err => console.error("Could not connected to Mongo"));
module.exports = app;
and my React Component is this, minus import statements. The render function only contains a button that has an onlclick that executes doThing()
constructor(props: any) {
super(props);
this.state = {
showHomePage: true,
showAnimalUploadSearch: false,
showProfile: false,
showAnimal: true,
apiResponse: "",
fName: "bob"
};
this.changeView = this.changeView.bind(this);
// this.callAPI = this.callAPI.bind(this);
// this.componentWillMount = this.componentWillMount.bind(this);
this.doThing = this.doThing.bind(this);
}
callAPI() {
fetch("http://localhost:9000/testAPI")
.then(res => res.text())
.then(res => this.setState({apiResponse: res}))
.catch(err => err);
}
componentWillMount(): void {
this.callAPI();
}
changeView() {
this.setState({showHomePage: !this.state.showHomePage});
this.setState({showAnimalUploadSearch: !this.state.showAnimalUploadSearch});
this.setState({showAnimal: true});
this.setState({showProfile: false});
}
doThing() {
Axios.post('http://localhost:9000/testAPI', ({firstName: this.state.fName}))
.then(res => console.log(res));
}
and finally, testAPI.js looks like this
const router = express.Router();
const axios = require('axios');
router.get('/', function(req, res, next) {
//res.send('API is working properly');
axios.get('http://localhost:3000')
.then(res => console.log("got it"))
.catch(err => err);
});
module.exports = router;
I want to be able to access and use the data that is sent from my react component so that I can query my database with user input in the future. The API does connect with my React code, and when the testAPI function only contains these lines:
const router = express.Router();
const axios = require('axios');
router.get('/', function(req, res, next) {
res.send('API is working properly');
});
module.exports = router;
the message can be displayed on my react app in the browser via the state.
If anyone could help me see what I am doing wrong, or maybe give me a clue as to what other options I can try, please let me know.
Thank you.
When you send post request from client side, it will be in body property of req object
const router = express.Router();
// you shoud listen post request
router.post('/', function(req, res) {
const { body } = req;
// do somethin with data which you recieved in body, save to database for example
// and send response to the client
res.json({ message: 'your data was saved'});
});
module.exports = router;
to send data to client use:
router.get('/', function(req, res) {
res.json({ data: 'Some data'}); // or res.send('some text') to send plain text
});
I am trying to pass html from a client(angularjs) app to server side (nodejs), i am trying to access the html via the req.body, but the object is always empty({}).
So on the client side, I just call the api passing the html:
generatePDF() {
const htmlBlock = document.getElementById("templateArea");
const htmlObj = {"element": htmlBlock};
this.pdfService.generatePDF(htmlObj).subscribe(
(response) => {
console.log("pdf generated");
},
(error) => {
console.log(error);
}
);
}
the angular service does a post call.
everything fine, since it reaches the api, but then i try to access via console.log the req.body, that shows me always empty, any suggestion (i have the bodyparser already).
my app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var router = express.Router();
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
next();
});
app.use('/',require('./routes/index'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
the route:
var express = require('express');
var router = express.Router();
var pdfGenerator = require('../controllers/pdfGenerator');
router.post('/pdfURL', pdfGenerator.pdfToUrl );
module.exports = router;
the controller
var express = require('express');
var router = express.Router();
var fs = require('fs');
var pdf = require('html-pdf');
//var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };
module.exports = {
pdfToUrl: function(req,res,next) {
console.log(req.body);
pdf.create('<div style="background-color:blue">a simple text</div>', options).toFile('./businesscard.pdf', function(err, res) {
console.log("asd"); // { filename: '/app/businesscard.pdf' }
if (err) return console.log(err);
console.log("asd"); // { filename: '/app/businesscard.pdf' }
});
}
};
I am using socket.io to make a MEAN app. I am sending a event through my node, the event is defined in my index.js file which is included in my app.js. I am getting a 404 error while running my angular app.
let express = require('express');
let router = express.Router();
let server = require('http').Server(express);
let io = require('socket.io')(server);
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
io.on('connection', (socket) => {
console.log('User connected');
socket.emit('hello',{
greeting: 'Hello agam'
});
});
module.exports = router;
My angular code where i have included socket.io and calling my node server
import { Component, OnInit } from '#angular/core';
import * as socketIo from 'socket.io-client';
#Component({
selector: 'app-home-component',
templateUrl: './home-component.component.html',
styleUrls: ['./home-component.component.css']
})
export class HomeComponentComponent implements OnInit {
constructor() {
}
ngOnInit() {
const socket = socketIo('http://localhost:3000');
socket.on('hello', (data) => {
console.log(data);
});
}
}
The error which I am getting while running the app:
zone.js:2935 GET http://localhost:3000/socket.io/?
EIO=3&transport=polling&t=M4aQ8Fg 404 (Not Found)
This is My app.js :
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var cors = require('cors');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(cors({origin: true, credentials: true}));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Add:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
...
// And at end of file
http.listen(3000, () => {
console.log('started on port 3000');
});
So I am using Node.JS with Express as my backend and my servlet for API. I'm using AngularJS as my front end.
Through many Google searches, I finally solved my problem of using ngRoute with AngularJS and Node.js. And ended up with this:
var index = require('./routes/index');
var auth = require('./routes/auth');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.use('/api/auth', auth);
app.use('/', index);
app.use('*', index);
This is of course an excerpt of my app.js file at the root of my project.
Now when I make a call to my /api/auth/ I get told that node.js can't find my view. If I remove the app.use('*', index) the API works again but 'ngRoute' doesn't work.
How can I get to a point where both are working together? I also want to keep the address bar url as clean as possible.
My project was started with a call to yo node using yeoman if that helps any in the file/folder structure of my application.
Update
I'm not getting any answers or comments so maybe providing my full app.js file will be helpful and help me figure this out. Here it is.
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var auth = require('./routes/auth');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api/auth', auth);
app.use('/', index);
app.use('*', index);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Update 2
I have come to notice that the statement "ngRoute doesn't work" is vague. If I remove app.use('*', index) I receive this error if I try to go to an address other than the base address. I also receive this error when trying to access theapi/auth
Error: Failed to lookup view "error" in views directory "/Users/mitch/websites/splatform/views"
Update 3
The index.js file that my routes in app.js refer to includes this as well.
app.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname, '../', 'views', 'index.html'));
});
But, API calls shouldn't be going to the index.js File. Should be going to Auth.js.
Update 4
As requested, here is my $routeProvider from AngularJS.
$routeProvider
.when('/', {
templateUrl: 'templates/home.html',
resolve: {
lazy: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load ('frontStyles');
}]
}
})
.when('/app/login', {
templateUrl: 'templates/login.html',
resolve: {
lazy: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load ('appStyles', 'appScripts');
}]
}
})
.when('/app/dashboard', {
templateUrl: 'templates/dashboard.html',
resolve: {
lazy: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load ('appStyles', 'appScripts');
}]
}
})
.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
Also here is a simple run down of my file structure
app.js
routes
--auth.js
--index.js
views
--index.html ( angularJS Base )
public
--directives
--fonts
--images
--javascripts
--stylesheets
--templates ( Views that angularjs uses in `ng-view`
Call api's routes first then angularjs index.
For example: routesWeb.js
'use strict';
var express = require('express');
var path = require('path');
module.exports = function(app) {
var path_web = path.resolve(__dirname, '..');
var path_origin = path.resolve(__dirname, '../../');
app.use('/scripts',express.static(path_web + '/scripts'));
app.use('/pages',express.static(path_web + '/pages'));
app.use('/node_modules',express.static(path_origin + '/node_modules'));
app.route('/*')
.get(function(req, res){
res.sendFile(path_web + '/pages/ng-index.html');
});
}
pessoaRota.js
'use strict';
module.exports = function(app) {
var pessoasCtrl = require('../controllers/pessoasController');
app.route('/api/pessoas')
.get(pessoasCtrl.obter_todos_pessoas);
app.route('/api/pessoas/:pessoaId')
.get(pessoasCtrl.obter_pessoa_por_id);
app.route('/api/pessoasFeias')
.get(pessoasCtrl.obter_pessoas_feias);
};
server.js
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
app.use(bodyParser.json());
app.use(cookieParser());
var server = app.listen(port, function(){
var host = server.address().address;
var port = server.address().port;
console.log("Aplicação está on nesse endereço http://%s:%s", host, port)
});
require('./api/routes/pessoaRota.js')(app);
require('./web/routes/routesWeb.js')(app);
For more go here.