That's my first-day learning Node.js and on making a basic server that basically renders 1 page containing a header tag, I get an error saying that the CSS file can't be loaded
That's my code:
const express = require('express');
const path = require('path');
const HOST = '127.0.0.1';
const PORT = 3000;
const app = express();
//app.use("/public", express.static(path.join(__dirname, "static")));
app.get('/', (request, response) => {
response.setHeader("Content-Type", "text/html");
response.sendFile(path.join(__dirname, "static", 'index.html'));
});
app.listen(PORT, HOST, () => {
console.log(`Running Server on ${HOST}:${PORT}`)
});
The HTML file:
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Hello World!</title>
<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>
<h1>Hello World From Node.js!</h1>
</body>
</html>
The Error:
File Tree:
I just want to be pointed at the missing part here for the css file to be linked with the HTML
Note: the CSS file is loaded when I directly run the HTML by browser
You can use express.static() (that you commented out) to serve static files.
According to docs you need
app.use(express.static(path.join(__dirname, "static")));
This way CSS should load. Any request like http://127.0.0.1:3000/css/index.css will be checked against static directory and if matching file is found Express will serve it.
If request does not match the file in that directory (for example http://127.0.0.1:3000/) Express will continue to look for other matching routes and will execute app.get('/', fn) because it'll match.
For reference, full code:
const express = require('express');
const path = require('path');
const HOST = '127.0.0.1';
const PORT = 3000;
const app = express();
app.use(express.static(path.join(__dirname, "static")));
app.get('/', (request, response) => {
response.setHeader("Content-Type", "text/html");
response.sendFile(path.join(__dirname, "static", 'index.html'));
});
app.listen(PORT, HOST, () => {
console.log(`Running Server on ${HOST}:${PORT}`)
});
UPDATED There are two ways to use express.static() as docs explain:
When calling app.use(express.static(path.join(__dirname, "static"))); (without a prefix specified) index.css file, for example, will be available at
http://127.0.0.1:3000/css/index.css
When calling app.use("/public", express.static(path.join(__dirname, "static"))); (with /public prefix) the same index.css file will be available under /public prefix at
http://127.0.0.1:3000/public/css/index.css
This approach counter-intuitive because index.html needs to be updated to load CSS from this prefix (and will only work when loaded via http://127.0.0.1:3000/, not when opened as a local file):
<link rel="stylesheet" type="text/css" href="./public/css/index.css">
you can load the static assets by creating a virtual path like
app.use('/assets',express.static(__dirname + '/public/css'));
where the public is the directory where all your assets are stored,in which CSS is the folder where is all your CSS file are stored , you can you the virtual path in the link tag , href attribute for loading the css ,eg: if you have template file ,you write in it ,the link tag i have tried with the same directory structure like yours and tried to emulate the bug and fixed the css load issue you can refer : https://github.com/ardnahcivar/Node.js-Code-/tree/master/11-17-18 the code
Related
Let's say i have a simple project, index.html and one .js file with a method:
<!DOCTYPE html>
<html lang="pl">
<HEAD>
<script src="controller.js"></script>
<meta charset="utf-8"/>
<title>Project</title>
</HEAD>
<body>
<textarea id ="someID" name = "textFieldName"></textarea>
<button onclick="showNewData()">Button</button>
<p id="score"></p>
</body>
</html>
function getText(){
value = document.getElementById('someID').value;
}
function showNewData(){
getText();
document.getElementById('score').innerHTML = "Current data: "+value;
}
I tried to do the same on localhost:3000. So i've done npm project with express and hbs dependencies. It start from server.js file:
const express = require('express');
const port = 3000;
const app = express();
app.set('view engine', 'hbs');
app.get('/', (req, res) => {
res.render('index')
})
app.listen(port);
In "views" folder i have hbs file looked the same like former index.html file but it can't use javascript method from external file. Does anyone know how to do that?
in hbs file
As far as the browser knows, it is HTML. Clients do not care, and cannot know, if an HTTP response is generated by reading a static file or dynamically with some form of server side processing.
src="controller.js"
The value of the src attribute has to resolve to a URL containing the JavaScript
app.get('/', (req, res) => {
res.render('index')
})
The only URL your web server knows about (and so will provide anything other than a 404 error for) is /.
If you want /controller.js to provide a JS file then you need to write code to make that happen.
How to handle static files is covered in the Express Getting Started Guide.
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
(I know this question have been asked many times in many form, but I tried a lot of solution and none work the way it should.. So maybe a solution adapted to my work would help me understand.)
Here is the structure of my project.
Here is the index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./../node_modules/bootstrap/dist/css/bootstrap.min.css">
<title>Document</title>
</head>
<body>
<nav class="navbar navbar-default ">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">Brand</a>
</div>
</div>
</nav>
<script src="../node_modules//bootstrap.min.js"></script>
<script src="./../node_modules/jquery/dist/jquery.js"></script>
</body>
</html>
And here is the server/app.js. I let the res.sendFile(); empty on purpose.
//export used
var express = require('express'),
url = require("url"),
path = require("path"),
fs = require("fs");
const _port = 3000
var app = express();
app.get('/', function(req, res){
res.sendFile();
});
app.listen(_port, function() { console.log('listening port '+_port+"\n__dirname : "+__dirname)});
The purpose of the server for now is just to send the index.html, that is one level up in the public folder. when a request in made to '/'. and I CAN'T DO IIIITT,
for several reason:
-I tried to use helmet to workaround Content Security Policy.
-I tried to use the static middleware to do stuff..
-I tried to use the path.join / resolve
So is there anyone who can explain somehow how to send this public/index.html file with the bootstrap scripts/css working ?
Have a nice day
Edit:
Here is the new app.js, it render the index.html thanks to the express.static but bootstrap css/scripts are not rendered :
//export used
var express = require('express'),
url = require("url"),
path = require("path"),
fs = require("fs");
const _port = 3000
var app = express();
app.use(express.static(path.join(__dirname, '/..', 'public')));
app.get('/', function(req, res){
res.sendFile('../public/index.html',{root: __dirname});
});
app.listen(_port, function() { console.log('listening port '+_port+"\n__dirname : "+__dirname)});
You have to add static middleware just after defining your app and before other routings because it is recommended to put static middleware first.
Use the path module to join the paths since it helps to avoid issues
of operating systems working differently with slashes and backslashes.
app.use( '/' , express.static(path.join(__dirname ,'..' ,'public'));
By doing this, you can serve all your static files in the public directory including scripts and css.
If you are using express, then you shouldn't serve single file instead you can make a static folder where all your js and css lies and you can serve that whole folder and use angular for routing.
Here is sample code:
var express = require('express'),
url = require("url"),
path = require("path"),
fs = require("fs");
const _port = 3000
var app = express();
app.use('/',express.static(__dirname+'public'));
app.use(bodyParser.json());
app.listen(_port, function() { console.log('listening port '+_port+"\n__dirname : "+__dirname)});
I want a file like index.html to be loaded when the server is created. When I execute the server.js using node, I send a response as text like this res.end("text"). But I want the index.html to load.
I tried to load it using sendFile() in app.get('/getFile') but when I type in the address bar, I get the text for all the urls..even for localhost:3000/getFile.
This is my server.js:
(function(){
var http = require("http");
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var path = require('path');
// app.use(express.static(__dirname));
app.use(bodyParser.json());
app.use(express.static(__dirname+'/views'));
var server = http.createServer(function(request, response) {
response.end("text");
});
server.listen('3000');
console.log("Server is listening");
app.get('/getFile',function(request,response){
// response.end('shi');
response.sendFile(path.join('/index.html'));
})
})();
Change the following in your code:
var server = http.createServer(function(request, response) {
response.end("text");
});
to this:
var server = http.createServer(app);
Now, you can serve your static index.html file with this code:
app.get('/', function(req, res, next){
// Serve the index.html file in the root directory of the website.
res.sendFile(path.join('/index.html'));
});
I hope this helps. If you have any questions, let me know.
EDITED
I just made a folder and wrote the following code and I have checked that this is working.
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/indexz.html');
});
app.listen(1339);
console.log('Open this link http://localhost:1337');
Steps
1 Copy the code given above in a new folder and name it whatever you want, name the file server.js
2 go to your cmd and propagate to location of your code and now npm install express
3 now type node server on console
4 open the link that is there on the console.
Note : Make sure there is folder name public and there is a file named
indexz.html in there.
Edited
Regarding proper client side files arrangement
You will have to keep all your files in public folder, first of all and attach them accordingly in your html document.
Example
<!-- Owl Carousel Assets -->
<link href="css/owl.carousel.css" rel="stylesheet">
<link href="css/owl.theme.css" rel="stylesheet">
<script src="js/jquery.min.js"></script>
<script src="angular.js"></script>
<script src="controller.js"></script>
and then within public folder you'll have folders named js and css and in root of the public folder your html files.
Looks your issue is with all the static assets.
In application server like express you have 3 different kind of elements to serve:
static content: this is all html, client side js, css, images and so on
server side templates or views, are documents you assemble with some sort of templating library like handlebars or jade to produce html
api that provide data in xml or more common json format
Your issue is how to serve a static part.
You should add to the static folder of your express app the folder where you build your angular app.
Not just the index.html you need the client side .js, .css and all images the page require.
UPDATE:
Here you could find the express documentation about static content.
UPDATE:
When you add a static folder to the express middleware, you should be able to access your file directly.
For example, if you have 2 files: $project/static/main.js and $project/static/js/my-lib.js, you should use the following urls:
http://127.0.0.1:3000/main.js
http://127.0.0.1:3000/js/my-lib.js
Considering you're executing the node http server on localhost on port 3000.
If you provide a specific path to access the static content, then you have to rewrite your url so.
If you use a line like:
app.use('/staticFolder', express.static('staticFolder'));
Than the urls to the mentioned files will be:
http://127.0.0.1:3000/staticFolder/main.js
http://127.0.0.1:3000/staticFolder/js/my-lib.js
Also pay attention to the path you provide to express.
You should give a proper path, and it's always safer to use absolute paths:
app.use(express.static(__dirname + 'staticFolder'));
or
app.use('/staticFolder', express.static(__dirname + 'staticFolder'));
Here is my current folder structure
css
app.css
js
app.js
node-modules
index.html
node-server.js
package.json
The node-server is hosting index.html, but I can't figure out how to get the app.js and app.css files to get loaded.
index.html loads them with:
<script src="js/app.js"></script>
<link rel="stylesheet" type="text/css" href="css/app.css"/>
Here is the error message:
Failed to load resource: the server responded with a status of 404 (Not Found)
2http://localhost:3000/css/app.css Failed to load resource: the server
responded with a status of 404 (Not Found)
I know i need to require or load module or something, just can't figure out what.
Thanks
Reason
Node.Js does not server static content on it's own, routes has to defined for serving static content via Node.
Solution(Manual):
var express = require('express'),
path = require('path'),
app = express();
app.get('/index.html',function(req,res){
res.sendFile(path.join(__dirname + '/index.html'));
});
app.get('/css/app.css',function(req,res){
res.sendFile(path.join(__dirname + '/css/app.css'));
});
app.get('/js/app.js',function(req,res){
res.sendFile(path.join(__dirname + '/js/app.js'));
});
app.get('/', function(req, res) {
res.redirect('index.html');
});
app.listen(8080);
Better Solution:
Directory Structure:
public
css
app.css
js
app.js
index.html
CODE:
var express = require('express'),
path = require('path'),
app = express();
// Express Middleware for serving static files
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res) {
res.redirect('index.html');
});
app.listen(8080);
As Tomasz Kasperek pointed out, you need to let Express know that you intend to host these files in a static directory. This is technically called defining static middleware.
This should look something like:
var express = require('express');
var app = express();
// first parameter is the mount point, second is the location in the file system
app.use("/public", express.static(__dirname + "/public"));
It's super simple and I suggest you go the route of making some sort of public folder, rather than bothering to make specific files and folders static.
Then the files would simply be referenced like so from the root index.html:
<link href="public/css/reset.css" rel="stylesheet" type="text/css">
Hope this helps you!
I got it to work by using this syntax
app.use(express.static('public'));
Copy the css and js files under the 'public' directory
and then add the reference in the index.html file
<link rel="stylesheet" href="/css/reset.css">
//we are in ./utils/dbHelper.js, here we have some helper functions
function connect() {
// connect do db...
}
function closeConnection() {
// close connection to DB...
}
//let's export this function to show them to the world outside
module.exports = {
connect(),
closeConnection()
};
// now we are in ./main.js and we want use helper functions from dbHelper.js
const DbHelper = require('./utils/dbHelper'); // import all file and name it DbHelper
DbHelper.connect(); // use function from './utils/dbHelper' using dot(.)
// or we can import only chosen function(s)
const {
connect,
closeConnection
} = require('./utils/dbHelper');
connect(); // use function from class without dot