"Stylesheet could not be loaded" error in Node/Express App - javascript

I am trying to load a stylesheet into my page through express, but there is no good reason as far as I can tell as to why it is not working. When I route to the file in a browser, I can see the CSS file, but there seems to be a problem with the app.use. Could anyone point out what I am doing wrong?
main.js
app.use('/css/stylesheet.css', function(req, res) {
let stylesheet = fs.readFileSync(path.normalize(__dirname+"/views/css/stylesheet.css"), 'utf8');
res.setHeader('Content-Type', 'application/css');
console.log(stylesheet);
res.send(stylesheet);
});
index.ejs
<link rel="stylesheet" type="text/css" href="/css/stylesheet.css">
My file directory:
.
|-views
| |-css
| | |-stylesheet.css
| |-index.ejs
|-main.js

I found the error, I set the Content-Type as "application/css" instead of "text/css", so the browser wouldn't load the css file.

Related

Rendering HTML file with res.sendFile() in Express.js

I'm trying to render my HTML file with some a local CSS file, local JS file and two remote files as links
but all I got is a plain HTML in the browser
here is the top of my HTML file (index.html):
<script src="src/drawflow.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="src/index.css" />
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
/>
This is my server code (app.js):
"use strict";
const express = require("express");
const path = require("path");
const app = express();
app.use(express.static(__dirname + "/src"));
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname + "/index.html"));
});
app.listen(process.env.port || 4000, () => {
console.log("listening to port 4000...");
});
and here is my file structure:
file structure
The index.html file is working just fine when opened in the browser but it can't be fetched properly from the server.
Any ideas ?
Thanks to the comment by Chris Short
I replaced
app.use(express.static(__dirname + "/src"));
to
app.use('/src', express.static(path.join(__dirname + '/src')));
and it worked perfectly.
Thanks a lot.
If I'm understanding correctly. The assets for your HTML file are not being fetched properly, so your HTML is showing as bare when you access through the browser. With this understanding, the reason your assets are not loading properly is due to the way your app.js is set up.
Currently you are trying to access href="src/index.css" in your header, however all of your assets are going to be found from your website root. Expressjs handles all app.use statements as middleware and by default are attached to the root of your website. If you would like to have this accessible from "src" then you will need to set up your express.static a bit differently like so.
app.use("/src", express.static(path.join(__dirname, "/src"));
See the below for more info
https://expressjs.com/en/starter/static-files.html
https://expressjs.com/en/guide/using-middleware.html

HTML <script> src url no longer works after rearranging files

I'm working on a personal project in order to learn web dev, and I've run into a strange (and hopefully easily solved) problem. In my index.html file I've included a reference to a main.js file, and that's been working just fine for a while now. However, I've recently rewritten the project in Typescript and I've decided to rearrange the folder structure. The problem is that when I move my index.html file (and some other files) down one directory and append a '../' to the script's 'src' tag, I get a 404 error when the html attempts to load the script.
This works just fine:
.
|-scripts
|-Main.ts
|-Main.js
|-SlideShowView.ts
|-SlideShowView.js
|-Server.ts
|-Server.js
|-index.html -> <script src="scripts/Main.js" type="module"></script>
This does not:
.
|-scripts
|-Main.ts
|-Main.js
|-SlideShowView.ts
|-SlideShowView.js
|-services
|-Server.ts
|-Server.js
|-index.html -> <script src="../scripts/Main.js" type="module"></script>
Connecting to the site when using the second scheme gives this error:
GET http://localhost:8000/scripts/Main.js net::ERR_ABORTED 404 (Not Found)
Is index.html not allowed to look above it's own directory? Is there a permissions issue or something? It's such a simple thing that's failing to work I figure there must be something small I'm missing.
Thanks in advance for the help!
Found the answer!
After I moved index.html back to root, the problem wasn't in my html or main.js, but in the express server I was using:
import path from "path";
import express from "express";
const serverPortNum = 8000;
const htmlFile = path.join(__dirname + '/../index.html'); //Added an escape here...
// Create html server
var app = express();
app.use(express.static(__dirname));// ...but not here.
app.get('/', function(req: any, res: any)
{
res.sendFile(htmlFile);
});
app.listen(serverPortNum, function()
{
console.log("Listening! (port " + serverPortNum + ")");
});
Basically, I had changed the path to the html file correctly but I forgot to make the change in app.use() as well. Changing that line to app.use(express.static(__dirname + "/..")); corrected the problem.
This should be simple as moving the index.html file outside of both file structures
|-scripts
|-Main.ts
|-Main.js
|-SlideShowView.ts
|-SlideShowView.js
|-services
|-Server.ts
|-Server.js
|-index.html -> <script src="scripts/Main.js" type="module"></script>

CSS file path doesn't work both on localhost and in text editor

So, I'm working on URL Shortener written in JS using Node.js and Express. I've just finished front end but I have a problem with getting css to work.
My project tree looks like this:
public
css
main.css
views
index.html
app.js
In my index.html file I have my .css file linked this way
<link rel="stylesheet" type="text/css" href="../public/css/main.css">
and it does work while making the site in Brackets editor, but when I launch localhost server CSS doesn't and I get
Cannot GET /public/css/main.css
I suppose it has something to do with my static path declared in app.js
app.use(express.static(path.join(__dirname, "public")));
because when I change the path in index.html to /css/main.css everything works on localhost but then my local text editor (Brackets) can't see that css file.
What should I do to make it work both during development in text editor and on localhost?
There are a couple of ways ( probably more ) :
Option 1
Go with your browser for debugging your application ( use only your app to see the modifications and not the brackets editor )
Option 2
Set your href="" attribute to a static location, e.g. href="localhost:8080/css/main.css". Then ( probably ) when you run your editor and the app simultaneously, you will get the same CSS file on both sides.
Option 3
Add another line of stylesheet to load them both.
<link rel="stylesheet" type="text/css" href="../public/css/main.css">
<link rel="stylesheet" type="text/css" href="/css/main.css">
The most common way to solve this problem, usually is Option 1, so you can just don't bother about bracket's internal browser and figure out a combination with live-reload module that will duplicate the extras that you get from your editor.
browser sends a get request to fetch a CSS file, you can add the following code snippet in you code:
var fs = require('fs');
var url = require('url');
var query = url.parse(req.url, true)
var pathname = query.pathname
var filepath = "./public/"
if(fs.existsSync(filepath+pathname)){
res.end(fs.readFileSync(filepath+pathname));
}
now in the html page :
<link rel="stylesheet" type="text/css" href="css/main.css">
Explained :
the browser will send a GET request for css/main.css
and the pathname will be then css/main.css
filepath is declared as ./public/
filepath + pathname will be ./public/css/main.css
fs.existsSync will return true and write the data in response.
becauase you filepath is ./public/ only files under public directory can be send in this method so your *app.js/ file is safe.
I have written this in synchronus manner using Sync functions you can do it using asynchronus manner too.
hope this helps

how to properly include fusioncharts.js into node express project using jade?

I tried
script(src="/fusioncharts.charts.js")
in the head of layout.jade, but it didnt work, error 404.
Then I tried via
layout.jade:
script(src="/charts")
app.js:
app.get('/charts', routes.charts);
index.js:
exports.charts = function(req, res){
res.sendFile(__dirname + "fusioncharts/fusioncharts.charts.js");
};
I get error : res.sendFile is not a function.
I have enide2015, project created with node_modules from enide.
I tried with -- router.get( ... - I got property undefined error
layout.jade:
doctype html
html( lang="en" )
head
title= title
meta( charset='utf-8' )
meta( http-equiv='X-UA-Compatible', content='IE=edge' )
meta( name='viewport', content='width=device-width, initial-scale=1.0' )
meta( name='description', content='Baking Bootstrap Snippets with Jade' )
//- Bootswatch Theme
link(href='//maxcdn.bootstrapcdn.com/bootswatch
/3.3.6/flatly/bootstrap.min.css',rel='stylesheet')
script(src="https://www.google.com/jsapi")
script(src="http://maps.google.com/maps/api/js?sensor=true")
script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js')
script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular-route.min.js')
//***************************
script(src="/fusioncharts")
//***************************
In other words, proper way to include external js local library, not CDN source ,ideally specifically fusioncharts ? Thank you.
EDIT: OK, found the problem, when creating node express project with Enide, there's pre-set environment in app.js, setting only PUBLIC folder accessible. I got now 200 OK message while accessing fusioncharts.js file.
I am still not able to render the chart itself, rendering ? Any suggestions ?
Found this trending on Reddit - talks about using FusionCharts with Node, Express and MongoDB.
http://www.fusioncharts.com/tutorials/creating-interactive-charts-using-node-express-and-mongodb/

Node.js Express not able to get static files and route is deeper then one folder level

Before I ask the question here is the folder structure of my node.js express app:
/home
server.js
index.html
/app
/routes
public.js
/public
/css
main.css
This is what I have in server.js:
// ROUTING FOR STATIC CONTENT
var public_dir = __dirname + '/public';
app.use(express.static(public_dir));
// INITIALIZE ROUTER
var public_router = express.Router();
// IMPORT PUBLIC ROUTES
require('./app/routes/public')(public_router, public_dir);
// REGISTER ROUTES
app.use('/', public_router);
This is what I have in /app/routes/public.js:
var path = require('path');
module.exports = function(public_router, public_dir) {
public_router.get('/new', function(req, res) {
res.sendFile(path.join(public_dir, 'index.html'));
});
public_router.get('/popular', function(req, res) {
res.sendFile(path.join(public_dir, 'index.html'));
});
public_router.get('/popular/today', function(req, res) {
res.sendFile(path.join(public_dir, 'index.html'));
});
}
Inside index.html I call css file like this:
<link rel="stylesheet" href="css/main.css">
The problem:
When I visit mydomain.com/new and mydomain.com/popular, css file is loaded and page is rendered properly. However when I visit mydomain.com/popular/today, css file is not loaded properly. In chrome dev tools I see that browser is trying to load css from popular folder which is incorrect.
Any ideas or comments would be appriciated.
Thanks in advance!
Change <link rel="stylesheet" href="css/main.css"> to <link rel="stylesheet" href="/css/main.css">.
Note the prefixing /. This will make the browser to start search in the root of the tree instead of using relative paths.

Categories