Everything works fine on local machine, Please let me if my server setup is correct
Project Structure
/client/--React frontend app
/client/package.json
/index.js
/package.json -- express server
In My /index.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require("path");
const app = express();
app.use(cors());
app.use(express.json());
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
app.listen(process.env.B_PORT || 5000, () => {
console.log(`Express server Up and Running - Port : ${process.env.B_PORT}`);
});
In My /client/package.json
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:5000",
}
I am getting 405 not allow for post request, but when i do http://myec2ip:5000 i can json response from express.
What config am i missing ?
You will need to open port 5000 in security group setting of ec2 and allow anyone to access it using 0.0.0.0 for incoming connections.
Related
Trying to make my first Vue application, simple game with MEVN stack. Working perfect interacting with backend on development environment, however when hosting it doesn't fetch the data from the server.
Anyone able to point out what I have incorrect with the below?
More info below:
File structure:
/root
|- config.js
|- server.js
|- package.json + package-lock.json
|- client/
|- vue.config.json
|- ... (rest of dist, src, node_modules, public etc.)
|- models/
|- Elf.js + HighScore.js
|- routes/
|- api/
|- elf.js + highScore.js
config.js
module.exports = {
hostUrl: process.env.HOST_URL,
mongoURI: process.env.MONGO_URI,
PORT: process.env.PORT || 3000,
};
server.js
const express = require("express");
const app = express();
const port = 3000;
const mongoose = require("mongoose");
const { PORT, mongoURI } = require("./config.js");
// routes
const Player = require("./routes/api/player");
const Elf = require("./routes/api/elf");
const HighScore = require("./routes/api/highScore");
// cors is a middleware that allows us to make requests from our frontend to our backend
const cors = require("cors");
// morgan is a middleware that logs all requests to the console
const morgan = require("morgan");
// body-parser is a middleware that allows us to access the body of a request
const bodyParser = require("body-parser");
const path = require("path");
app.use(cors());
// use tiny to log only the request method and the status code
app.use(morgan("tiny"));
app.use(bodyParser.json());
// chek if we are in production
if (process.env.NODE_ENV === "production") {
// check if we are in production mode
app.use(express.static("client/dist"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "dist", "index.html"));
});
}
// test if server is running and connected to mongoDB
app.get("/", (req, res) => {
res.send("Hello World!");
});
// app.get("/", (req, res) => {
// res.send("Hello World!");
// });
// use routes
app.use("/api/", Player);
app.use("/api/", Elf);
app.use("/api/", HighScore);
mongoose
.connect(mongoURI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useUnifiedTopology: true,
})
.then(() => console.log("MongoDB connected..."))
.then(() => {
// log uri to console
console.log(`MongoDB connected to ${mongoURI}`);
})
.catch((err) => console.log(err));
app.listen(PORT, () => {
console.log(`Example app listening at ${PORT}`);
});
package.json
{
"name": "week1",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"server": "nodemon server.js --ignore 'client/'",
"client": "npm run serve --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"start": "node server.js",
"build": "npm install --prefix client && npm run build --prefix client"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.20.1",
"bootstrap": "^5.2.3",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"mongoose": "^6.7.5",
"morgan": "^1.10.0",
"portal-vue": "^2.1.7"
},
"devDependencies": {
"concurrently": "^7.6.0",
"nodemon": "^2.0.20"
}
}
Running within my dev environment at root dir using 'npm run dev', the app works flawlessly send/ receive data from mongoDB during this time. This starts up http://localhost:8080/. Also tried install of 'npm install -g serve' and running 'serve -s dist', this starts up serving at localhost:36797 and working flawlessly too.
I have tried to setup on Vercel & Render, both giving me the same issue where I'm not getting much feedback and the data isn't being fetched. Anyone else has this issue before?
I have a Front End application which is mainly based on React, and I have created a node server to serve the application. Build and everything are successful, and the the index.html is also served, but it doesn't read the environment variables that I set through heroku application settings (even from CLI).
Package.json scripts
"scripts": {
"start": "node server",
"start-dev": "react-scripts start",
"start-windows": "set PORT=3001 && react-scripts start",
"build": "react-scripts build",
"postinstall": "npm run build",
"test": "jest src/**/*.test.js",
"eject": "react-scripts eject"
}
node server,
const express = require ('express')
const app = express();
const http = require('http').Server(app);
const path = require( 'path')
let port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'build') + '/index.html');
});
app.listen(port, () => {
console.log(`App running on port ${port}`);
});
I print followings in a js,
console.log('LOCAL_TEST_ENVIRONMENT --- ', process.env.LOCAL_TEST_ENVIRONMENT) // LOCAL_TEST_ENVIRONMENT --- undefined
console.log('BACKEND_URL --- ', process.env.BACKEND_URL) // BACKEND_URL --- undefined
console.log('NODE_ENV --- ', process.env.NODE_ENV) // NODE_ENV --- production
Environment variables I set,
How can I fix this?
The prefix REACT_APP_ is necessary when accessing env variables, try
{process.env.REACT_APP_LOCAL_TEST_ENVIRONMENT}
Trying to configure proxy in react native with node to run axios calls.
Tried the following code in server/package.json
"proxy": {
"/*": {
"target": "http://localhost:5000/"
}
},
"scripts": {
"start": "node index.js",
"server": "nodemon index.js",
"client": "cd ../client && yarn ios",
"dev": "concurrently \"yarn server\" \"yarn client\""
}
server/authRouter.js
const authRouter = require('express').Router();
authRouter.get('/test', (req, res) => {
res.send('proxy success');
});
module.exports = authRouter;
server/index.js
const express = require('express');
const authRouter = require('./authRouter');
const app = express();
app.use('/auth', authRouter);
const PORT = process.env.PORT || 5000;
app.listen(PORT);
client/app.js
await axios.get('/auth/test');
When I run yarn dev and test an axios call, it logs the following error
LOG [Error: Network Error]
any help would be much appreciated.
Try calling the proxy directly in axios
http://localhost:5000/auth/test
I'm not sure why it doesn't work that way, even i had a problem in the past.
The issue I am having is my React application hosted on Heroku is calling "https://localhost:8000" for it's calls to the Express server.
I have the proxy in package.json set to https://localhost:8000 to call my Express server. From my understanding this is all I need to do and Heroku handles the connection when it is deployed.
When I go to my endpoint like so: https://heroku-app.herokuapp.com/v1/products/:productid my Express server successfully sends back JSON data in the browser, so I do know my Node server is up and running on Heroku. The issue seems to be the React app proxy is not calling the Heroku URL post-deploy.
Here is my React apps package.json:
{
"name": "client",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"proxy": "http://localhost:8000/",
"devDependencies": {
"enzyme-matchers": "^7.0.2"
}
}
This is the package.json file for my server:
{
"name": "stub_boilerplate",
"version": "1.0.0",
"description": "Quick Stub",
"main": "server.js",
"scripts": {
"test": "jest",
"start": "node server/server.js",
"heroku-postbuild": "cd client && npm install --only=dev && npm install && npm run build"
},
"engines": {
"node": "~9.10.1",
"npm": "~5.6.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/manm/xxx.git"
},
"author": "Maison M",
"license": "MIT",
"bugs": {
"url": "https://github.com/maonm/xxx/issues"
}
}
Here is my server.js file. I am setting the port to process.env.PORT || 8000:
const express = require('express');
const app = express();
const port = process.env.PORT || 8000;
//Allows access to enviroment variables in development
require('dotenv').config({ path: __dirname + '/.env' });
//Middleware
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(methodOverride('_method'));
//Serve build folder of client
app.use(express.static(path.join(__dirname, '../client/build')));
app.use('/v1/products', product_routes);
//Error handling
app.use(errorHandler);
//Initialize Express server
app.listen(port, err => {
if (err) console.info(`Error: The server failed to start on ${port}`);
else console.info(`****** Node server is running on ${port} ******`);
});
This is the fetch() request inside of the component:
componentDidMount() {
this.fetchStripePlans();
}
fetchStripePlans = () => {
const stripeProduct = 'prod_FlXXXXXBVn8'; //QS (product)
const url = `http://localhost:8000/v1/products/${stripeProduct}`;
const fetchConfig = {
method: 'GET',
headers: {
'content-type': 'application/json'
}
};
fetch(url, fetchConfig)
.then(data => data.json())
.then(stripe => {
const { data } = stripe;
this.setState({
stripePlans: data
});
})
.catch(err => {
this.setState({
error: true,
errorMessage: err.genericError
});
});
};
This is what I am seeing in the console of the React app:
SignUpContainer.js:48 OPTIONS http://localhost:8000/v1/products/prod_FRon8 net::ERR_CONNECTION_REFUSED
So to me logically, it's not being routed to the Heroku URL. I've scoured a few tutorials on deploying React/Express projects to Heroku and all of them leave the React proxy set to the local host of the Express server. So I am not too sure what is happening here.
In order to make use of the proxy value in your package.json, you must specify a relative URL in your fetch request, such as /v1/products/${stripeProduct}. You should not include the hostname or port in your component.
For reference, see "Running the server and the React app" and "Using the proxied server from React" sections in here: https://www.twilio.com/blog/react-app-with-node-js-server-proxy
Although a GET request usually qualifies as a simple request, the fact that the Content-Type is set as application/json qualifies it as a pre-flight [1] request. Therefore, what happens is that the browser sends a HTTP request before the original GET request by OPTIONS method to check whether it is safe to send the original request.
Try enabling CORS Pre-Flight for your route handler sending the application/json response. You can do this by using the cors [2] middleware in the options handler for your route, like such:
const express = require('express')
cosnt cors = require('cors')
const app = express()
app.options('/products/:id', cors()) // enable pre-flight request for GET request
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
[1] https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
[2] https://www.npmjs.com/package/cors
I'm trying to upload an express/node.js app to heroku. The app is deployed succesfully but when I try to access the url I get error: Not Found.
When I run heroku logs --tail I get:
Error: ENOENT: no such file or directory, stat '/client/build/index.html'
so I think I'm doing something wrong with the directories and the statics folder
this is my server.js file:
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const cors = require("cors");
const path = require("path");
const users = require("./routes/api/users");
const profile = require("./routes/api/profile");
const matches = require("./routes/api/matches");
const app = express();
//body-parser middleware
app.use(bodyParser.urlencoded({ extended: false, limit: "50mb" }));
app.use(bodyParser.json({ limit: "50mb" }));
//db config
const db = require("./config/keys").mongoURI;
//cors
app.use(cors());
//connect to mongoose
mongoose
.connect(db, { useNewUrlParser: true })
.then(() => console.log("MongoDB connected"))
.catch(err => console.log(err));
//Passport middleware
app.use(passport.initialize());
app.use("/images", express.static(path.join(__dirname + "/images")));
//Passport config
require("./config/passport")(passport);
//Use route
app.use("/api/users", users);
app.use("/api/profile", profile);
app.use("/api/matches", matches);
//Serve static assets if in production
if (process.env.NODE_ENV === "production") {
app.enable("trust proxy");
//Set static folder
app.use(express.static(path.join(__dirname, "/../client/build")));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname + "/../client/build/index.html"));
});
}
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`server running on port ${port}`));
I also include an image of the folders "positions"
I solved this issue by defining build and install command in my package.json. Heroku would look for a build command for production in there.
"scripts": {
"build": "cd client && npm run build",
"install": "cd client && npm install",
"start": "node server",
"server": "nodemon server",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
},
I think it should be like this
app.use("/images", express.static(path.join(__dirname, "images")));
Edit: Actually your app is expecting to find a file at /../client/build/index.html but that file does not exist (which is what ENOENT error means). So you either need to create the expected directory structure or else configure your application such that it looks in the correct directory for index.html. That whats i understand now, i hope this would help you.
I also got similar error. For me the problem is I have wrong script for build in package.json file, So build is not creating at all.
Verify you have "heroku-postbuild" script as below in package.json file.
"scripts": {
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"clientinstall": "npm install --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},