Javascript files not loading when hosting a website on digital ocean - javascript

I've built a web app with an express backend and using the ejs view engine.
When I run it on my computer it works fine but I'm trying to host in on digitalocean. I cloned it to the droplet(Ubuntu 22.10 x64) and served it on port 80. When I visited it in the browser at 46.101.145.210:80, I got these errors.
GET https://46.101.145.210/javascripts/cookieHandler.js net::ERR_CONNECTION_REFUSED
GET https://46.101.145.210/javascripts/domain.js net::ERR_CONNECTION_REFUSED
Here's my file structure,
Here's the code in index.js.
const express = require("express");
const app = express();
const fs = require("fs");
const path = require("path")
const assert = require("assert");
const PORT = 80
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use(express.static('public'));
app.set("view engine", "ejs")
app.listen(PORT, () => {
console.log("Server running on port " + PORT.toString());
});
const domains = ... // Not important
app.get("/", (req, res) => {
res.render("index")
//res.redirect("/domain")
})
app.get("/domain", (req, res) => {
res.render("domain", {domains: domains})
})
I've tinkered with the firewall config and the express.static to see if it would make a difference. I couldn't figure anything out though.
Update: I've checked the requests out a bit. They are https requests. When I use postman and change the request to be http it works.

I solved it by adding a valid ssl certificate.

Looking your file structure and the code, I can say, you must define the full path of the public directory using
express.static(__dirname+'/public')
Or can be like
const path = require('path');
// .... your code ...
app.use(express.static( path.join(__dirname, 'public') ));
with this you are forcing to define where the public directory is on the ubuntu, and validate you are accessing your files
Hope you can solve with this
Update: checking carefully, I can see that your are trying to request using https, but your code is working on port 80 (http), so you said, on postman worked without https because of the port. If you want to have working your code with port 443 (https), you must have a certificate (with domain but not required), then try with https://46.101.145.210/javascripts/cookieHandler.js otherwhise try http://46.101.145.210/javascripts/cookieHandler.js.

Related

Why is my server showing error on the browser "This site can't be reached ERR_UNSAFE_PORT" even when it is running perfectly on the terminal?

I made a index.html file and index.js and server.js.
Inside server.js I have written the following code:
const express = require("express");
const path = require("path" );
const app = express();
app.use("/static",express.static(path.resolve(__dirname, "frontend", "static")));
app.get("/*", (req,res)=>{
res.sendFile(path.resolve(__dirname,"frontend","index.html"));
});
app.listen(process.env.PORT || 5060, ()=> console.log("Server Running..."));
No error is shown by the vs code and it is working fine in terminal but giving error msg when I am trying to load the application on chrome browser with localhost:5060 url with ERR_UNSAFE_PORT error. Please suggest some way to resolve this.
So, there are a bunch of ports which are considered unsafe by chrome browser which includes 5060 which you were specifying earlier. That's why earlier you were getting "ERR_UNSAFE_PORT" error when you were trying to load localhost:5060.
From the program perspective, there isn't anything wrong. And at first glance everything will look okay. The problem starts when chrome identifies the port and declares it unsafe. This is done by the browser to prevent XSRF so, that someone doesn't use chrome as a proxy to attack your services.
How do you know which are the ports we are not supposed to use? Refer at this link which provides a list of blocked ports on chrome browser - https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/net/base/port_util.cc
Final program would look like:
const express = require("express");
const path = require("path" );
const app = express();
app.use("/static",express.static(path.resolve(__dirname, "frontend", "static")));
app.get("/*", (req,res)=>{
res.sendFile(path.resolve(__dirname,"frontend","index.html"));
});
app.listen(process.env.PORT || 3001, ()=> console.log("Server Running..."));

Run multiple Node.js apps on the same server

I want to run multiple Node js apps on the same server, and so far I made some progress checking solutions for similar questions here (links below). Let's say I have 2 apps, each serving some html file, and I'd like to access each by visiting
https://example.com/app1 and
https://example.com/app2
So far, I have my main app, and my approach was to call this app which will then redirect a client to one of these 2 apps.
My main app looks like this:
const express = require('express');
const app = express();
app
.use('/app1', require('./app1/index.js'))
.use('/app2', require('./app2/index.js'))
.listen(80);
Each of my two sub-apps (app1 and app2) looks like this
const express = require('express');
const bodyParser = require('body-parser');
const routes = require('./routes/api');
const mongoose = require('mongoose');
require('dotenv/config');
const app = express();
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true, useUnifiedTopology: true }, () =>
console.log('Connected to DB')
);
mongoose.Promise = global.Promise;
app.use(express.static('public'));
app.use(bodyParser.json());
app.use('/', routes);
app.use(function (err, req, res, next) {
res.status(422).send({ error: err.message })
});
The issue is that I don't get anything after deploying these apps and visiting e.g. https://example.com/app1
I'm super new in all this so there is likely a beginner's mistake in here. Can anyone help?
Related questions How to mount express.js sub-apps? and Running multiple Node (Express) apps on same port
If you want to run totally different application in node you might use proxy_pass/reverse proxy of apache/nginx.
To do so each of your app should operate on theirs own ports and some other server (apache/nginx/etc) passing requests to each of them
example for apache: https://www.digitalocean.com/community/tutorials/how-to-use-apache-as-a-reverse-proxy-with-mod_proxy-on-ubuntu-16-04 sadly with python examples as apps, but the principle is the same.
example for nginx https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
Im hosting several node apps using this technique and they are working really nice (nginx is much faster than apache). Also you might thinking about blocking access from internet to node apps ports directly.

ngrok Cannot GET / local server up and running

I'm trying to follow Crowdbotics' Messenger bot tutorial, however. I did exactly as he mentioned but i am getting this.
My folder:
Okay so, first of all i run node index.js and get the following:
Right after that. We initialize our ngrok server by ngrok http 5000 and get the following:
But on EVERY http request i get the classic Cannot GET /.
On the hindsight, my index.js only contain:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(5000, () => console.log('Webhook server is listening, port 5000'));
I can't really point out what i am doing wrong, your help is truly appreciated.
Based on your express js code, I think you haven't define the routes to '/'
add this before the app.listen on the index.js file
app.get('/', (req, res) => res.send('Hello World!'))
Your index.js has started a server that listens and respond to the HTTP protocol - but it does not "serve files" the same way a web server such as Apache does.
As #Yana notes, you need to explicitly set a route to do something, such as send a text response back.
If you want the favicon.ico file to be sent when requested, then you need to setup a static route for that as part of your index.js code.

How to auto refresh browser during development when static assets are sent via Express?

How do I automatically refresh the browser when I make changes to my client files? I am building the client using ReactJS. I am telling my Express server to send the static assets located in my public directory when a GET request is made to "/".
Here is how my server looks:
const express = require('express');
const path = require('path');
const logger = require('morgan');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 1128;
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// static assets
app.use(express.static(path.resolve(__dirname, './../public')));
app.listen(port, () =>
console.log(`server is listening on port: ${port}`)
);
After making changes, webpack bundles everything and outputs everything into the public directory. Is there a way for the server to watch for changes here so the browser could automatically refresh? If anyone knows how or knows of a better way I'd greatly appreciate. Thanks!
You could have a websocket which notifies clients on file changes. You can detect file changes using fs.watch()
Watch file system: https://nodejs.org/api/fs.html#fs_event_change
Web socket: https://socket.io/ (or your library of choice)
socket.on('file_changed', function () {
location.reload();
});

Running deployd and angular.js app on the same server

I'm trying to run a deployd API on the same server as my AngularJS app, but deployd seems to be conflicting with the app routing.
My deployd server is listening on port 5000 and looks like this:
var deployd = require('deployd');
var server = deployd({
port: process.env.PORT || 5000,
env: 'production',
db: {
host: 'localhost',
port: 27017,
name: 'deployd',
credentials: {
username: 'myUsername',
password: 'myPassword'
}
}
});
server.listen();
server.on('listening', function() {
console.log("Server is listening");
});
server.on('error', function(err) {
console.error(err);
process.nextTick(function() { // Give the server a chance to return an error
process.exit();
});
});
My node server for the AngularJS app is listening on port 3000 and looks like this:
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(process.env.PORT || 3000);
The app loads fine, although it is not hitting the API as expected when making a call like this:
$http.get('localhost:5000/foo')
or this:
$http.get('http://my.public.ip.address:5000/foo')
And my page routing (in HTML5 mode, with no # in the URL) is getting hijacked by deployd -- so a URL routed by AngularJS for '/foo' is hitting the API and returning "Cannot GET /foo".
This is all happening on a server that is also running Apache, but that is configured to forward requests for my domain to port 3000 using something like this:
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster#localhost
ServerName my.domain.com
ProxyPreserveHost on
ProxyPass / http://localhost:3000/
<Location />
Order allow,deny
Allow from all
</Location>
</VirtualHost>
If I use the # in the URL, like http://my.domain.com/#/foo that will return the page template dictated by the AngularJS router, but it is missing data because the API is not being hit on port 5000.
Any help would be greatly appreciated.
Turns out this was a problem with my Express server.js code and had nothing to do with Deployd. I kept seeing the Cannot GET /foo message and just assuming Deployd was trying to fetch a resource, but in fact Express was not loading index.html (which loads AngularJS and my routing code), because it was just trying to load a static file called foo instead.
Here is my fixed server.js:
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(function(req, res) {
res.sendfile(__dirname + '/public/index.html');
});
app.listen(process.env.PORT || 3000);
Now, if the static file foo does not exist, it loads index.html and allows my AngularJS router to take the wheel.
have you checked that from a browser that port 3000 as well as 5000 is reachable?
Because you are using proxy pass it makes me think that those ports aren't open. And because angular is run client side, it will never be able to connect to the api if the 5000 port is closed.

Categories

Resources