I used this https://medium.com/weekly-webtips/create-and-deploy-your-first-react-web-app-with-a-node-js-backend-ec622e0328d7 to create React Front End and NodeJS backend. On running locally, it worked but I deployed it on Heroku. I didn't receive any response from express server api.
app.get("/test/", (request, response) => {
response.send({"name":"Hello Test!!!"});
});
my proxy setting looks like this
Result in http://localhost:3000/
Hello from the frontend!
Hello Test!!!
Result in https://react-node-js-test.herokuapp.com/
Hello from the frontend!
"proxy": "http://localhost:5000",
server.js
// Import dependencies
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
// Create a new express application named 'app'
const app = express();
// Set our backend port to be either an environment variable or port 5000
const port = process.env.PORT || 5000;
// This application level middleware prints incoming requests to the servers console, useful to see incoming requests
app.use((req, res, next) => {
console.log(`Request_Endpoint: ${req.method} ${req.url}`);
next();
});
// Configure the bodyParser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
// Configure the CORs middleware
app.use(cors());
// This middleware informs the express application to serve our compiled React files
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
};
// // Catch any bad requests
// app.get('*', (req, res) => {
// res.status(200).json({
// msg: 'Catch All'
// });
// });
app.get("/test/", (request, response) => {
response.send({"name":"Hello Test!!!"});
});
// Configure our server to listen on the port defiend by our port variable
app.listen(port, () => console.log(`BACK_END_SERVICE_PORT: ${port}`));
Any help would be great
// MOVE THIS BEOFRE get("*")
// Because * will handle all incoming requests
app.get("/test/", (request, response) => {
response.send({"name":"Hello Test!!!"});
});
// This middleware informs the express application to serve our compiled React files
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
};
Related
I'm trying to make initial connection between my node js with apache2 web server backend to my React frontend. I'm newbie at all of this and trying to make it work on local machine before deployment.
I read about CORS and solve an issue with access origin headers with it, but I can't understand what am I missing here.
the server runs and listening to port 3000
the frontend on port 3001
my frontend code is:
import React from 'react';
import axios from 'axios';
import logo from './logo.svg';
import './App.css';
export default class App extends React.Component {
state = {
persons: []
}
componentDidMount() {
axios.get(`/ping`, {
headers: {
"Access-Control-Allow-Origin": "*"
}
})
.then(res => {
const persons = res.data;
this.setState({ persons });
})
}
render() {
return (
<h1>dfdfdfdfdf{this.state.persons}</h1>
)
}
}
And My Backend code is:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var cors = require('cors');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
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(cors());
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
const hostname = '127.0.0.1';
const port = 3000;
// 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');
});
app.use(express.static(path.join(__dirname, 'build')))
app.get('/ping', (req, res) => {
return res.send('pong')
})
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'))
})
app.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
module.exports = app;
I keep getting the errors:
Failed to load resource: the server responded with a status of 404 (Not Found)
0.chunk.js:779
Unhandled Promise Rejection: Error: Request failed with status code 404
(anonymous function) (0.chunk.js:779)
promiseReactionJob
I'm learning how to build a RESTful api with Node and Express, and I am having an issue with this https request. I am trying to make a GET request to Scryfall's api (documentation here: https://scryfall.com/docs/api), but whenever I run my server and check the browser I get a message stating
"localhost didn’t send any data. ERR_EMPTY_RESPONSE".
As I'm new to using Node and Express, I'm not really sure what I am doing wrong. Here is the code for my server.js and app.js files.
//server.js
const https = require('https');
const app = require('./backend/app');
const port = process.env.PORT || '3000';
app.set('port', port);
const server = https.createServer(app); //pass the express app to the server
server.listen(port);
and
//app.js
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('This is the first middleware');
next();
});
app.get('https://api.scryfall.com/cards/named?fuzzy=aust+com', (req, res, next) => {
res.send('${res.body.name} is the name of the card!');
});
module.exports = app;
Any help would be greatly appreciated! Thanks in advance!
👨🏫 For an example, you can do it with this code below 👇:
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
console.log('This is the first middleware');
next();
});
app.get('/', async (req, res, next) => {
try {
const result = await axios.get('https://api.scryfall.com/cards/named?fuzzy=aust+com');
res.status(200).send(result.data);
}catch(ex) {
console.log(ex.message);
}
});
app.listen(3000, () => {
console.log('Server is up');
})
💡 From the code above, you can call the endpoint: localhost:3000 and than you will get the result.
I hope it's can help you 🙏.
You can easily make a get request like this.
const express = require('express');
const app = express();
const port = 8080;
const bodyParser = require('body-parser');
//Expect a JSON body
app.use(bodyParser.json({
limit: '50mb' //Request size - 50MB
}));
app.get('/test', (req, res, next) => {
// do whatever you need here
res.status(200).send("ok");
});
app.listen(port, function () {
console.log(`Server is running.Point your browser to: http://localhost:${port}`)
});
I've created a React and node/express based app and trying to deploy it on heroku. The deployment went well and my app is available here: https://sbansal-campaign-manager.herokuapp.com/
However, there is a problem in calling backend apis and loading data even though the requests return 200 response.
When I click Preview tab, however, it says: You need to enable JavaScript to run this app. which is incorrect. JS is enabled. I'm able to access the data on my local machine but not when I deploy the app on heroku. Sharing my server's configuration below:
const express = require("express");
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
// IMPORT MODELS
require('./models/Campaign');
const app = express();
mongoose.Promise = global.Promise;
mongoose.connect(
process.env.MONGODB_URI ||
`mongodb://<user>:<password>#ds145230.mlab.com:45230/sbansal-campaigns-db`
);
app.use(bodyParser.json());
//IMPORT ROUTES
require('./routes/CampaignRoutes')(app);
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
const path = require("path");
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`app running on port ${PORT}`);
});
I'm new to deploying stuff on heroku. Please help figure out the issue.
Here is the full repo: https://github.com/saranshbansal/sbansal-campaign-manager
The reason why it works on your machine is because you're defining:
if (process.env.NODE_ENV === "production") {
...
}
When you deploy to Heroku, you're deploying the master branch and it will be running in production mode.
This code clearly states that you want to return the html page for all routes:
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
The most probable reason is that your index/server.js (Node App File) looks something like this:
// DEV and PRODCTION HANDLER
if (process.env.NODE_ENV === 'DEV') {
const morgan = require('morgan'),
cors = require('cors')
app.use(morgan('dev'),
cors({ origin: `${process.env.HOST_IP}:${process.env.CLIENT_PORT}` })
)
}
if (process.env.NODE_ENV === 'PROD') {
const { resolve } = require('path')
app.use(express.static(resolve(__dirname, '..', 'dist')))
app.use('*', (req, res) => {
res.sendFile(resolve(__dirname, '..', 'dist', 'index.html'))
})
}
// WEB APP ROUTES
app.use('/api/', require('./api/Home.controller'))
app.use('/api/user/', require('./api/User.controller'))
app.use('/api/user/dashboard/', require('./api/Dashboard.controller'))
app.use('/api/chatbot', require('./api/Chatbot.controller'))
app.use('/api/transactions', require('./api/Transactions.controller'))
Which is completely wrong, I was also getting the same error, while doing the research I found this question and after this, I also found the official recommended way to actually use the routes, which clearly suggests that a get route should be used that to server the react files.
Here's the link to doc:
https://create-react-app.dev/docs/deployment/#serving-apps-with-client-side-routing
What happening here is, that express is serving the response from //DEV and PRODUCTION HANDLER. There are 2 problems with the above-given code
//DEV and PRODUCTION Handler should use app.get('') instead of the app.use('') for serving the react HTML build file.
res.sendFile should be below all the other routes.
Here is also a very good blog by https://medium.com/#abdamin for deploying a MERN app: https://itnext.io/deploy-a-mongodb-expressjs-reactjs-nodejs-mern-stack-web-application-on-aws-ec2-2a0d8199a682
So finally, the correct code would look something like this:
// DEV and PRODCTION HANDLER
if (process.env.NODE_ENV === 'DEV') {
const morgan = require('morgan'),
cors = require('cors')
app.use(morgan('dev'),
cors({ origin: `${process.env.HOST_IP}:${process.env.CLIENT_PORT}` })
)
}
// WEB APP ROUTES
app.use('/api/', require('./api/Home.controller'))
app.use('/api/user/', require('./api/User.controller'))
app.use('/api/user/dashboard/', require('./api/Dashboard.controller'))
app.use('/api/chatbot', require('./api/Chatbot.controller'))
app.use('/api/transactions', require('./api/Transactions.controller'))
if (process.env.NODE_ENV === 'PROD') {
const { resolve } = require('path')
app.use(express.static(resolve(__dirname, '..', 'dist')))
app.get('*', (req, res) => {
res.sendFile(resolve(__dirname, '..', 'dist', 'index.html'))
})
}
You need to enable CORS in your server-side app.
Like bellow, or create your customized:
// Setup CORS
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With,
Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
return res.status(200).json({});
}
next();
});
I have simple express server in node:
const express = require('express')
const path = require('path')
const application = express()
const port = process.env.PORT || 80
const PUBLIC_DIR = 'public'
application.use(express.static(path.join(__dirname, PUBLIC_DIR)))
application.listen(port)
//handle 404
application.use((req, res) => {
res.send('404: Page not Found', 404)
});
//handle 500
application.use((error, req, res, next) => {
res.send('500: Internal Server Error', 500)
});
console.log(['HTTP server running on ', process.env.HOST, ' / ', port].join(''))
When I put "builded" react app into folder public, server return index.html good. But problem is in react routers.
I have routers like this:
/
/home
/about
When I go to url localhost/ - works fine, return index html with full app, but problem is when I go to /home, /about, server return 404, how to fix it? How to redirect to react route? I hope you understand me.
Thank you for any help
after you build the react try using :-
app.use(require('body-parser').json({ limit: '50mb' }));
app.use(require('body-parser').urlencoded({ limit: '50mb', extended: true, parameterLimit: 1000000 }));
app.use(express.static(path.join(__dirname, '../client')));
switch (process.env.NODE_ENV) {
case 'production':
app.use(express.static('./client/build/'));
app.use('/', express.static('./client/build/index.html'));
break;
default:
app.use(express.static('./client/'));
app.use(express.static('./', config.staticOptions));
app.use('/', express.static('./client/index.html'));
break;
}
Try to return all the routes from index.html as follows:
const express = require('express')
const path = require('path')
const application = express()
const port = process.env.PORT || 80
const PUBLIC_DIR = 'public'
application.use(express.static(path.join(__dirname, PUBLIC_DIR)))
application.listen(port)
app.use(express.static('client/build')); //use your build path my build path under the root folder is client/build
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client','build', 'index.html')); //use your build path my build path under the root folder is client/build
});
//handle 404
application.use((req, res) => {
res.send('404: Page not Found', 404)
});
//handle 500
application.use((error, req, res, next) => {
res.send('500: Internal Server Error', 500)
});
console.log(['HTTP server running on ', process.env.HOST, ' / ', port].join(''))
I am trying to post using restler and return the response to client but response never returns .Below is code I am using and response is just hanging
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var rest = require('restler');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = 3001; // can also get it from process.env.PORT
var router = express.Router();
//this is like interceptor for every route to validate all requests, logging for analytics
router.use(function (req, res, next) {
console.log('route intercepted');
next(); // make sure we go to the next routes and don't stop here
});
router.get('/', function(req, res) {
res.json({ message: "welcome to restful node proxy layer to business processes" });
});
router.route('/someroute').post(function(req, res) {
rest.postJson('http://localhost/api/sg', req.body).on('complete', function(data, response) {
console.log(response);
}
).on('error', function(data, response) {
console.log('error');
});
});
app.use('/api', router); //all routes are prefixed with /api
app.listen(port);
console.log("server is running magic happens from here");