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.
Related
I have deployed an AWS LightSail Node server with Express on it.
Starting the app on port 3000 correctly activates app.js and display in the browser the projected string (http://my.ip.address:3000):
Welcome to the Whiteboard server! this is the home page on port 3000 with base dir: /opt/bitnami/apache/htdocs/whiteboard
This is the app.js:
const express = require("express");
const app = express();
const port = 3000;
global.__basedir = __dirname;
app.use(express.json());
app.listen(port, () => {
console.log(`Whiteboard listening on port: ${port}`);
});
app.get("/", (req, res) => {
res.send(`Welcome to the Whiteboard server! this is the home page on port ${port} with base dir: ${__basedir}`);
});
However, Trying to request any file residing in the root folder (...apache/htdocs/whiteboard) such as:
http://my.ip.address:3000/Jeanette_Blog1.png
http://my.ip.address:3000/index.html
Always returns this message in the browser:
Cannot GET /Jeanette_Blog1.png
Shows as 404 error in the console.
Btw, although the path shows apache, I have actually installed node with needed modules and express - as can be seen in the app.js file up here. The apache is just part of the node image AWS LightSail creates through their partner Bitnami.
What am I missing?
An express server by itself does not serve any files by default. If you want to serve a directory or a directory hierarchy of static files, you have to use express.static() (or something similar) in a route definition.
You should not configure express.static() to point at the same directory that contains your server code because that would enable people to look at your server files. It is a popular convention to make a sub-directory (often called "/public", either below or at the same level as your server files. Here's an example with express.static() configured for a directory at the same level. You would add this line:
app.use(express.static(path.join(__dirname, "../public")));
And, it would all look like this:
const express = require("express");
const app = express();
const path = require('path');
const port = 3000;
global.__basedir = __dirname;
// serve public files
app.use(express.static(path.join(__dirname, "../public")), {index: false});
app.use(express.json());
app.listen(port, () => {
console.log(`Whiteboard listening on port: ${port}`);
});
app.get("/", (req, res) => {
res.send(`Welcome to the Whiteboard server! this is the home page on port ${port} with base dir: ${__basedir}`);
});
Then, you would move your static files such as index.html and Jeanette_Blog1.png to that /public directory. They can be referred to from the browser as URLS such as /index.html and /Jeanette_Blog1.png. The express.static() middleware will check the incoming path to see if it matches a filename in the /public directory and, if so, it will serve it. If it doesn't match a file, then it will continue routing to other route handlers you have defined.
I am deploying a Node.js Express app to a VPS by Render. When I run the app on my local machine, the npm start command does a great job of serving my file when I point the browser to localhost:3001. However, after I deploy, the base directory '/' returns "Not found". I have to point my browser to example.onrender.com/public/index.html.
How do I make sure that example.onrender.com/ routes the request to public/index.html?
Thank you!
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res) {
res.render('index.html');
});
app.listen(3001);
Actually just had to change "Publish Directory" settings in Render to ./public
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.
const express = require('express');
const path = require('path');
const app = express();
app.listen(9000);
app.get('/test', function(req, res) {
console.log("not being hit");
res.send(200);
});
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function (req, res) {
console.log("always hits");
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
This seems like such a simple problem but my brain is starting to turn to mush.
Here's the details:
I have run build on a react app and the index.html file resides in the build folder, and I want this served via express.
I want express to prioritize /test first, and if it's not /test, then I want it to serve the index.html file in the build folder.
If you go to /test, it is skipped and always hits the /* route. If you remove the wild card and use / instead, neither routes will hit if you go to / or /test in the browser. However, index.html is still served and it looks like that's because of the static middleware.
Everything I have read suggests that order in express is important, but I feel like I'm losing my damn mind and I'm starting to slowly descend into madness.
Thanks in advance.
I have created a RESTful service using Node.js and ExpressJS. Now I would like to implement View part. For this I have chosen AngularJS.
Problem here is, I am not sure how to organize folder structure and how to integrate AngularJS with Node.js and ExpressJS.
I watched this video, but for this no sample source code available.
Let's Get CRUDdy: AngularJS and Node.js Ferrari Example
Project folder structure
ExpressJS file
var express = require('express'),
http = require('http'),
path = require('path'),
photos = require('./routes/photos');
var app = express();
app.configure(function () {
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser());
app.use(app.router);
});
app.get('/photos', photos.findAll);
app.get('/view1', photos.index);
AngularJS:
// Declare app level module which depends on filters, and services
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
When I hit url http://www.domain/view1, it should display index.html. But I am getting 404 code.
Please let me know if you need more info on it.
If you're using AngularJS to implement a single-page experience then you should serve the same front-end code every time, and then have AngularJS take over processing the URLs and displaying the content.
Remember that you are managing two routing systems. One for the front-end and one for the backend. Express routes map to your data, usually returned in JSON format. (You can also render html directly, see Option #1.) Angular routes map to your templates and controllers.
Option #1:
Set static folder to serve front-end code (HTML/CSS/JS/AngularJS).
app.use(express.static(__dirname + '/public'));
Look at these for sample code:
https://github.com/btford/angular-express-seed
https://github.com/btford/angular-express-blog
Directory Structure:
public/
index.html
js/
angular.js
css/
partials/
partial1.html
partial2.html
app/
node_modules/
routes/
web-server.js
Option #2:
Serve the front-end code and backend code on separate servers.
This doesn't mean you have to have two machines.
Here is a workable set up on your local machine with Apache:
Directory Structure:
public/
index.html
js/
angular.js
css/
partials/
partial1.html
partial2.html
node/
app/
node_modules/
routes/
web-server.js
Set up hosts file
127.0.0.1 domain.dev
Set up http://domain.dev/ to point to public/
<VirtualHost *:80>
DocumentRoot "/path/to/public"
ServerName domain.dev
ServerAlias www.domain.dev
</VirtualHost>
Set up http://api.domain.dev/ to point to the running node web-server
<VirtualHost *:80>
ServerName api.domain.dev
ProxyPreserveHost on
ProxyPass / http://localhost:3000/
</VirtualHost>
(Adapted from: http://www.chrisshiplet.com/2013/how-to-use-node-js-with-apache-on-port-80/)
Start (or restart) Apache and run your node server:
node web-server.js
Angular Routes:
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives',
'myApp.controllers'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
index.html:
<!DOCTYPE html>
<html>
<head><title>Angular/Node exmaple</title></head>
<body>
<div id="main" ng-view></div>
</body>
</html>
Express Routes:
app.get('/', photos.index);
app.get('/photos', photos.findAll);
Access these routes in an Angular controller via $http or $resource service:
$http.get('http://api.domain.dev/photos').success(successCallback);
Additional Resources:
https://github.com/ithkuil/angular-on-server/wiki/Running-AngularJS-on-the-server-with-Node.js-and-jsdom
http://briantford.com/blog/angular-express.html
https://stackoverflow.com/a/10444923/243673
I had an existing angular project with a file structure like this (roughly):
/
app/
img/
scripts/
styles/
templates/
index.html
test/
I just created a new express app, and copied the contents of my app directory over to the /public directory in express, after removing all the existing content from /public
Then in the app.js file in express I did the following changes to the default config:
var express = require('express');
var routes = require('./routes');
// ** required my route module
var menu = require('./routes/menu');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
// ** I moved this above the app.router line below, so that static routes take precedence
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
// ** removed the default index route
// app.get('/', routes.index);
// ** defined my route
app.get('/api/menu', menu.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Then obviously wrote my route file in express and changed the URL in the angular service to use the new api.
Also there was more work involved deciding where to put the specs and also merging the bower and node dependancies etc but that is probably too specific to my situation to include with this answer but happy to share if anyone might find it useful.