Node.js web app uploaded through A2 Hosting - pathing issue with CSS - node.js

I am currently studying node.js and pretty new still so I apologize in advance for probably having an inefficient or terribly formatted first question. I am uploading a one-page test to figure out how to use A2's node.js service.
So far I have followed the A2 tutorial "How to create a Node.js application with cPanel using Node.js Selector" (https://www.a2hosting.com/kb/cpanel/cpanel-software/create-application-with-nodejs-selector) and this tutorial on syncing git repositories (https://medium.com/#pampas93/host-your-node-js-app-on-shared-hosting-go-beyond-localhost-73ab923e6691) and I have been able to get everything working except the main page
(Located in dirname/repositories/test/views/home-visitor.ejs)
will not read the CSS file I have uploaded
(Located in: dirname/repositories/test/public/main.css)
and some of the images do not load. No file name typos or forward slash "/" syntax inconsistencies, all images share the same folder path.
(Located in: dirname/repositories/test/public/images)
So the node.js app shows up as plain HTML only. I have uploaded the exact same app/git repository to Heroku and the CSS is read and all images show up, so I am trying to figure out what pathing issues I am having when uploading specifically to A2's hosting service.
When I check 'inspect' on the browser for the non-working app page, I get these console messages:
"Refused to apply style from 'http://domainname.com/main.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled."
Failed to load resource: the server responded with a staus of 404 () nonWorkingImageExample.png:1
Failed to load resource: the server responded with a staus of 404 () anotherNonWorkingImageExample.png:1
http://domainname.com/test/main.css sends to a 404 page
app.js:
const express = require("express")
const app = express()
let port = process.env.PORT
if (port == null || port == "") {
port = 3000
}
app.use(express.static("/public/"))
app.set("views", "views")
app.set("view engine", "ejs")
app.get("/test", function (req, res) {
res.render("home-visitor")
})
app.listen(3000)
The page I am testing: home-visitor.ejs:
<!DOCTYPE html>
<html><head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<header>
<div class="forMobile mobileHeader">
<div class="mobileLogo">
<a href="#"><img src="images/workingImageExample.png" alt="Image Description">
</a>
</div>
</div>
</header>
<div class="forDesktop centerContent tempMssg">"Lorem flexitarian salvia offal umami. Sartorial swag drinking portland cray. Godard jianbing retro thundercats hella tilde. "
<br><br>
<a href="#" target="_blank" rel="noopener noreferrer">
<img src="images/nonWorkingImageExample.png" alt="Twitter Logo Link" width="35px" height="35">
</a>
</div>
<div class="forMobile mobileUpperBG">
<img src="images/anotherNonWorkingImageExample.png" alt="upper left bg image">
</div>
</html>
I am hoping someone familiar with hosting node.js apps on A2 can help, and thank you for the time reading this question regardless.

Full credit for this solution goes to VictoryFlame's video
https://www.youtube.com/watch?v=BAD5JyOymRg.
I ended up editing the way app.js pathed my public folder and updated how I linked the CSS and image files in my .ejs file:
app.js:
const express = require("express")
const app = express()
const path = require("path")
app.set("views", path.join(__dirname, "views"))
app.set("view engine", "ejs")
app.use("/test1/static", express.static("public/"))
app.get("/test1", function (req, res) {
res.render("home-visitor")
})
app.listen()
I re-formatted the style link to the CSS page and used this pathing syntax for images:
home-visitor.ejs:
<link rel="stylesheet" href="https://domainname.com/test1/static/home.css">
<a href="#" target="_blank" rel="noopener noreferrer">
<img src="/test1/static/images/imageWorksNow.png" alt="Twitter Logo Link" width="35px" height="35"></a>
Now everything is properly served/linked and showing up. I hope this helps someone else some day!

Related

Why my css file is not loading when deployed in heroku? P.S: I'm using ejs

I have deployed my app on heroku. Using Node.js + Express + ejs.
But for some reason it is not loading my css.
Errors :
Unchecked runtime.lastError: The message port closed before a response was received.
Refused to apply style from 'https://**.herokuapp.com/public/css/styles.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
Failed to load resource: the server responded with a status of 404 (Not Found)
These are the errors I'm getting. When I inspect the page.
My file structure :
File Structure
app.js code
const express = require("express");
const bodyParser = require("body-parser");
const date=require(__dirname +"/date.js");
const app = express();
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(bodyParser.urlencoded({extended: true}));
header.ejs code
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>TO-DO LIST</title>
<link href="css/styles.css" rel="stylesheet" type="text/css" >
</head>
Please someone help me with this issue.
Edit :
The above mentioned errors (1 and 3) are not due to the code. They are due to the added extensions to my browser.
After removing the extensions error 1 and error 3 were gone. But error 2 still present.
After rigorous research and trying so many ways finally I'm able to resolve my issue by myself.
I have done some major changes, and my issue was resolved.
I have changed my file structure a little bit.
From this to this
I have created a new directory called partials in the views directory and moved my header.ejs and footer.ejs files to that directory.
In header.ejs file I have changed the code from this
<link href="css/styles.css" rel="stylesheet" type="text/css" >
to
<link href="/css/styles.css" rel="stylesheet" type="text/css" >
In other .ejs files I have included the header.ejs and footer.ejs as follows:
<%- include("partials/header"); -%>
<%- include("partials/footer"); -%>
And that's how I am able to solve my issue.
Hakuna Matata

Why is it that when I send a simple file from express, the client consumes a lot of memory?

When I open the html file from the browser it consumes the following:
But when I send the same file from an Express server, the memory consumption is noticeably higher:
It is true that this is not a huge memory consumption, but it is a VERY noticeable difference, Why is this happening?, is Express sending the client something that I do not know (headers, cookies, something?)?
From the server I just have a single JavaScript file with a single route that sends the html file using Express's sendFile function:
const express = require('express');
const { join } = require('path');
const server = express();
server.get('/', (_, res) => {
res.sendFile(join(__dirname, 'render.html'));
});
server.listen(3000, () => {
console.log('Server is running in port 3000');
});
whereas the HTML file you send to the client simply contains the following:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<header>
<h1>This is Header</h1>
</header>
<main>
<section>
<h1>Section 1</h1>
</section>
<section>
<h1>Section 2</h1>
</section>
</main>
<footer>
<h2>This is Footer</h2>
</footer>
</body>
</html>
there is nothing else.
I tried it from Google Chrome and Edge, I hope you can help me understand c:
They were neither HTTP headers, nor cookies ... much less the server, the problem was the extensions for the browser !!!
Apparently when I open the HTML file locally (using the 'File:' protocol) the extensions were not running.
This is interesting for me, I don't know how the browser extensions work and their life cycle, but apparently the extensions share the processes and the memory in the current tab, that is, they share the process and the memory with the application that is being currently running, it wasn't my memory consuming application, it was browser extensions processes.

Azure app uploads from VSCode without linking static sources

I have an incredibly basic node.js server test app running on port 3000 in VSCode. The server appears to work via node on localhost or deployed to Azure, and hosts an index.html file. I have clients happy to talk to it.
/* Server.js */
const express = require('express');
const app = express();
app.use(express.json());
app.get("/", function(request, response){
response.sendFile(__dirname + "/index.html");
});
app.post("/", function(request, result){
console.log(request.body["itema"] + " " + request.body["itemb"]);
result.send("Pong!!");
});
app.listen(3000, function(){
console.log("Server started on port 3000");
});
<!-- Index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Simple App</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
</head>
<body>
<h1>Test!</h1>
</body>
</html>
/*style.css*/
h1 {
color: tomato;
}
Azure Configuration Settings
The index.html links to a css file which doesn't appear to be linked when deployed. I've tried deploying the app to azurewebsites.net through VSCode, however I'm seeing the same results. Only index.html is present in the sources view. I get an error claiming it can't render the source it didn't find.
"Refused to apply style from https://<appname>.azurewebsites.net/style.css because its MIME
type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is
enabled."
If I view the advanced page (.scm.azurewebsites.net), again I can see only index.html.
Index only
But .scm.azurewebsites.net/wwwroot/ shows me the css file has been uploaded correctly.
Index and linked sources
I'm convinced it'll be a simple solution to someone and that the PATH variables will need to be set...somehow... but I've hit a brick wall and my Google-Fu has finally been exhausted.
Thanks!
Adding the following to server.js resolved the issue.
app.use(express.static("./"));
This is further explained here and is required in express to serve static files.
https://expressjs.com/en/starter/static-files.html

iframe embedded YouTube video unavailable on NodeJS

I was trying to implement a simple player with a web server on a VM when I stumbled across this issue.
server.js
const express = require('express');
var app = express();
var path = __dirname + '/views/' ;
app.get("/",function(req,res,next){
res.sendFile(path + "index.html");
});
app.listen(1823);
console.log('listening');
index.html
<!DOCTYPE html>
<html>
<head>
<title>Alpha</title>
</head>
<body>
<iframe id="player" width="640" height="360" src="http://www.youtube.com/embed/N0dbGGvsjf8?enablejsapi=1&origin=http://192.168.150.129">
</iframe>
</body>
</html>
Accessing the site locally with http://localhost:1823 works just fine.
However, accessing the site from the local network such as http://192.168.150.129:1823 the iframe(?) stops working.
Screenshot
Same video works on JSFiddle.
NB: This only happens on certain videos.
e.g. with this iframe
<iframe id="player" type="text/html" width="640" height="360" src="http://www.youtube.com/embed/PfYnvDL0Qcw?enablejsapi=1&origin=http://192.168.150.129">
</iframe>
Both localhost and IP work the same.
All seems to point towards Node doing something?
Why some videos work and others do not?

Serving HTML to build a simple SPA using Node.js/Express

I want to build a website as a Single Page Application.
For what I understand a SPA sends a single entry point to the application in the form of an HTML file.
So I would like to use Node and Express to serve the main page and to then serve HTML for the content between the header and footer that gets updated using AJAX calls when a user navigates the site.
I know how to create a restful API to serve data as JSON but not much on how to deal with the HTML parts of the SPA that are changing.
The question: how could this serving of HTML parts be implemented on the server using Node and Express (and eventually a template engine like handlebars, if it helps)?
And does it actually make sense? (A header and a footer are not much data to reload after all.)
You can definitely do this with node.js. First you set up an HTML template engine, for instance Swig, (but you can use others) and you configure the standard options to render html pages:
var swig = require('swig');
app.set('view engine', 'html');
app.set('view options', {
layout: false
});
app.engine('html', swig.renderFile);
app.set('view cache', false);
// To disable Swig's cache, do the following:
swig.setDefaults({ cache: false });
app.use(express.static(__dirname + '/public'));
Second you set up an endpoint which serves your main HTML page.
app.get('/',function(req, res) {
res.render('index');
};
Then you can create node.js endpoints which will get your data:
app.get('/users', function(req, res) {
// Do database stuff here
res.status(200).send(results);
}
Then you set up your HTML file:
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="stylesheets/bootstrap.min.css" rel="stylesheet">
<title>fast MEAN</title>
</head>
<body ng-controller="MainController">
<div class="col-md-12" style="background-color: #006699">
</div>
{% raw %}
{{helloWorld}}
<ng-view></ng-view>
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="app.js"></script>
{% endraw %}
</body>
</html>
Where everything outside of {% raw %} and {% endraw %} will be rendered with data using the node/swig template data, and everything inside those tags can be rendered with whatever framework you are using inside (jquery, angular, react) etc.
An example of this simple single page application is on my github, there's one version for angular and one for react. Hope that helps.
https://github.com/coguy450/fastMEAN

Resources