Apache: How to Serve Both PHP and NodeJS - node.js

I have a PHP site https://example.com.
I have a MEAN stack application subdomain http://team.example.com. It uses APIs provided by nodejs on port 3000.
I'm facing a problem when running the application on http://team.example.com where the Nodejs API is not reachable .
added the following to Apache Config File:
ProxyPass /node/ http://localhost:3000/
I am sending api request from angular side with the following:
team.example.com/node/users/login
APIs reached successfully via postman , but fails on browser
How can I solve this problem?

I think you have CORS issue, I'm assuming that you are using express framework in your node service.
See the following sample code to know how to solve CORS issue for browser.
var http = require('http');
var express = require('express');
var app = express();
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Methods','GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
app.post('/test-cors', function (req, res) {
res.set('Content-Type', 'application/json');
res.send(JSON.stringify({ 'status': "OK" }));
});
// Create http server and run it
var server = http.createServer(app);
server.listen(8081, function() {
console.log("Listening on 8081");
});
In above sample code you need to focus on following code lines:
app.use(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');
next();
});

Blockquote
For using the proxy you have to enable the proxy module in apache. After that restart the apache.
If you are using ubuntu os run following command
sudo a2enmod proxy &&
sudo a2enmod proxy_http
After this, you have to run
sudo service apach2 restart.

Related

getting 404 on my Express app after deployment

I have an app that run normally in local development but when I deploy it (Ubuntu 21.x server) I run node/pm2 start (even installed nodemon to try) I get 404 error(not my 404 page). That how I deployed it after logging to server:
sudo apt update
sudo apt upgrade
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
git clone (repo)
cd (repo)
npm install
then I run it with
node app.js
//or
pm2 start app.js
//even using nodemon
nodemon app.js
and I installed Nginx and I get their welcoming HTML when I refer to IP address but I get 404 when I go the project port 3000
that's my server code except the POST req:
const express = require('express');
const helmet = require('helmet');
const compression = require('compression');
const bodyParser = require('body-parser');
// express app
const app = express();
app.use(helmet);
app.use(compression());
// bodyparser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// listen for request
app.listen(process.env.PORT || 3000);
// miidleware static files
app.use(express.static('public'));
app.use(express.static('script'));
app.get('/', (req, res) => {
res.sendFile('./views/index.html', { root: __dirname });
});
app.use((req, res) => {
res.status(404).sendFile('./views/404.html', { root: __dirname });
});
spent around 12 days trying so would appreciate help very much.
It seems that the server you have deployed on has an open port 80, but not port 3000.
If you want to access your express app via port 3000, you need to open the port on the Ubuntu server. How to do this depends on a vast number of variables from where the server is located to what firewall you are using.
If what you are trying to do is have your express app shown by Nginx on port 80, you will need to create a reverse proxy using Nginx.
To do this, read up on this here. There are too many variables for us to help further

How to configure Node.js in Web hosting?

I made a website with create-react-app with a contact form that communicates with the backend (nodejs with nodemailer). In localhost works perfectly.
When I uploaded the website in a web hosting (wnpower.com/web-hosting is the hosting I bought) that supports nodejs apps, I can't use the contact form because I get "net::ERR_CONNECTION_TIMED_OUT" in the path "https://mywebsite.com/api/sendmessage". It seems the frontend can't find the backend router or something that I can't understand.
In the CPanel of the web hosting, in the terminal I installed Nodejs and ran a test app, works perfectly. But when I want to use node app across the frontend, doesn't work.
My configuration in the node app.js file:
require("./config"); // all process.env
const express = require("express");
const path = require('path');
const app = express();
const bodyParser = require("body-parser");
// ALL ROUTES
const contact_routes = require('./routes');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.listen(process.env.PORT, () => {
console.log("Server listening at port "+process.env.PORT);
});
// Configure Header HTTP
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method"
);
res.header("Access-Control-Allow-Methods", "GET, POST");
res.header("Allow", "GET, POST");
next();
});
app.use(express.static(path.join(__dirname, '../public_html')));
// CONNECT ROUTES WITH API
app.use(process.env.API_URL, contact_routes);
module.exports = {
app
};
public_html directory are the static files that I built with the command npm run-script build and the __dirname is the server folder. So:
Directory:
public_html -> static files frontend.
server -> node app, routes, controllers, etc.
And in the config.js file there is the process.env.PORT and the port is 3050.
In the routes.js:
var express = require('express');
var controller = require('./controller');
var router = express.Router();
router.post('/sendmessage', controller.sendMessage);
module.exports = router;
in the .htaccess file:
DirectoryIndex ""
RewriteEngine On
RewriteCond %{REQUEST_URI} ^.*/index.*
RewriteRule ^(.*)$ http://127.0.0.1:3050/ [P,L]
RewriteRule ^$ http://127.0.0.1:3050/ [P,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://127.0.0.1:3050/$1 [P,L]
I can't understand well, I have no experience in that.
My idea is
Run the node app with nohup in the terminal of cpanel so the Node app will always running. Checked!
Try the contact form in the frontend website. Fail! I get timeout connection and I get nothing.
In the node app.js I want to see the console.log() in the terminal cpanel when I use the contact form. It's for test and know thats all is ok, but I can't see anything in the terminal. How can I do that?
If any information is missing, tell me I'll share the code. I need to resolve this as soon as possible. Thank you for reading and sorry for my English.
Try using
https://mywebsite.com:3050/
instead of http://127.0.0.1:3050/
at all places in your .htaaccess file
You can get logs of nohup from tail command in its log file.

React & Express server not getting api requests in production /build

I have a React app running successfully locally and all api requests are successfully running from a separate server.
When I run a build, the path to the api server is lost and no data is loaded.
Below are a few screenshots...
Loading data successfully from api.
Pointing IIS to react /build folder using localhost:80. No data loading.
Here is an example of an api call in my node/express server/index.js file
app.get('/api/company', (req, res) => {
api_helper.GET('https://****/api/company')
.then(response => {
res.json(response)
})
.catch(error => {
res.send(error)
})
})
My package.json file has the url of the express proxy (running in the background).
"proxy": "http://localhost:5000/",
My question is, why isnt the api loading in production /build? I just get this...
Request URL: http://localhost/api/site
Request Method: GET
Status Code: 404 Not Found
Remote Address: [::1]:80
Referrer Policy: no-referrer-when-downgrade
but when just running locally (npm start) I get this and data loads from api.
Request URL: http://localhost:3000/api/site
Request Method: GET
Status Code: 304 Not Modified
Remote Address: 127.0.0.1:3000
Referrer Policy: no-referrer-when-downgrade
Any help appreciated, driving me mad! Thanks.
After much testing I discovered, you must put the routes before
Wrong Example:
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.use('/', routes);
Right Example:
app.use('/api', routes);
app.use(express.static(path.join(__dirname, 'build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
For anyone else struggling with this, I figured it out..
I had to add this to my express server.js file in the root folder of my project.
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
I then pointed to the address where express is running, in my case http://localhost:5000
This worked.
I also then set up a rewrite rule in IIS to point localhost and our domain name to localhost:5000
All working now, hope it helps someone else.
Thanks for your info. I am quite new to ReactJS and I also encountered similar problems when I created my production build. Actually I had added similar things like
app.use(express.static(<build_folder_dir>));
in my Express Server before then I came to search and see your post. Anyway, I did not add something like the second line of your code and my API calls are written in router created in a separate js file.
app.use('/api/some_path', <imported_router>);
In the exported router object, codes are written like this:
router.get('/some_sub-path')
To make API calls, I used axios in my react app
axios.get(
"/api/some_path"+"/sub-path?param_1="+<param_value>,
{
headers:{
"Content-Type":"application/json",
<some headers>
}
}
).then((res)=>{<Some codes using the res.data.<any param in body>>})
Finally,I added these lines in the server.js
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, <path of the index.html in the build dir>), function(err) {
if (err) {
res.status(500).send(err)
}
})
})
Yet, I made a stupid mistake that my app crashed because the app.get overwrite the settings in router. Just a reminder, if you enable any API calls in GET method, use regex to exclude the pattern for making API calls.

Connecting reactjs with nodejs

I have an app with front end react and backend node. The backend is tested with postman and working fine. the front end ui is tested with static data. Now I have set up a proxy with the react part to connect to the backend node.
My react app is runnning on port 3000
my node is running on port 5000.
When I request a route on my backend from my front end the app does not utilize the proxy set up Instead it gives me a Bad request error.
My front end is in client folder .Please help.
the project can be found on the following github link
https://github.com/prashantbhat84/mern-contactkeeper
Please help
It seems to be a cross-origin problem. There are two ways to solve cross-origin problems in node server,
Using cors node module
First install cors module. npm install cors
and then use it inside your app
const Express = require("express");
const BodyParser = require("body-parser");
const Cors = require("cors");
const app = Express();
app.use(Cors());
app.use(BodyParser.urlencoded({ extended: false }));
app.use(BodyParser.json());
app.listen(3001, 'localhost', (err) => {
if(err) {
console.log(err);
process.exit(-1);
}
console.log("Server listen port 8083");
});
simply use following headers
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");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
next();
});
NPM uses a configuration file and it can be added to via the command line npm config set. The key to getting it right is the spelling of the settings. This has bit me so many times now! Getting npm to work behind a proxy requires setting the proxy and https-proxy settings. The key is noticing the - (dash) is not an _ (underscore).
Open an command prompt or terminal session and run the following commands to configure npm to work with your web proxy. The commands use domain_name.com as the address and 8080 as the port.
npm config set proxy http://domain_name.com:8080
npm config set https-proxy http://domain_name.com:8080

Why is my server causing a syntax error when deployed to Heroku but runs with no errors locally (using Create React App, Node/Express)?

Edit to add picture of exact error, and to provide more info
When I click on main.35...js in the error message in the console, it shows me the source code to my index.html, all of it with the red underline, but I don't see the erroneous syntax there:
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"><title>BoGoodSki.com</title><link href="/static/css/main.4d5a52c0.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="/static/js/main.35eb4822.js"></script></body></html>
Also, in development, there is no error or warning in VSCode regarding the index.html file. I'm confused for sure.
Thanks for the help so far!
End edit
I have an app deployed to Heroku that has been working well.
Today I made some changes to the Express server to handle a simple API post request to a MongoDB instance on mLab. I had to set up CORS policy as middleware but, otherwise, I didn't make any substantial changes to the server code.
My deployment flow has been to run 'npm run build' on the Create React App client, and then use the Heroku CLI to git push from my server folder. This process has worked well. Until today.
Now, when I deploy to Heroku, it says that it publishes successfully, but the app is blank in the browser and the console says that there is a syntax error of < in the build JS file. I can't currently reproduce the error because I rolled back to a working deployment in Heroku.
Here is my server code. Can you identify what may be causing the issue? My JS build files sit in client/build/static, just like Express expects them to, so I don't know what's up.
Appreciate the help.
index.js:
const express = require('express');
const mongoose = require('mongoose');
const keys = require('./config/config');
require('./models/FormData');
var bodyParser = require('body-parser');
mongoose.connect(keys.mongoURI);
const app = express();
const FormMessage = mongoose.model('formMessages')
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(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.post("/submitMessage", (req, res) => {
var newMessage = new FormMessage(req.body);
newMessage.save()
.then(item => {
res.status(200).send();
})
.catch(err => {
res.status(400).send();
});
});
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);
Fixed!!
Okay. Here are the steps that I took. I'm not sure which, individually, resolved the problem. But, altogether, they worked.
First, I deleted the existing main.35...js file in my source code direetory. Actually, I deleted the entire build/static folder. And then ran "npm run build" in the client directory to rebuild the React app.
I changed the node engine in my package.json from 8.1.1 to the version I am running locally, 9.2.1.
In my index.js, I removed the conditional regarding the production environment variable because, it occurred to me that it didn't make sense to serve it up differently locally than I would in production; I think that conditional was a remnant from something I had been working on earlier in the project.
Those steps taken together have done the trick. I appreciate all who have viewed this question and given it any thought. Thanks!

Resources