Node.js won't send CSS in response - html

I'am trying to set up a client/server program with node.js.
I have the following code, which returns a .html file when connected.
JavaScript:
var http = require('http');
const fs = require('fs');
var server;
fs.readFile('./FrontPage.html', function (err, html){
if (err){
throw err;
}
server = http.createServer(function (req, res) {
res.writeHead(200, {
"Content-Type": "text/html"
});
res.write(html);
res.end();
console.log("HTTP response sent");
});
var port = 3000;
server.listen(port, function () {
console.log("Server listening on port " + port);
});
});
HTML:
<head>
<link rel="stylesheet" type="text/css" href="./css/FrontPageCSS.css">
</head>
<body style="background-image:url(./img/bg.jpg)">
<div id="header">
<img src="./img/Logo.png" height="5%" width="5%" alt="logo">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="./script/FrontPageJS.js"></script>
</div>
<div id="buttonWrapper">
<div id="first" class="first">
This is my first button
</div>
<div id="second" class="second">
This is my second button
</div>
</div>
When I access localhost on port 3000 in my browser, it returns the .html file without the CSS. When I open the .html individually via it's path, the CSS works just fine.
My question: Why is the CSS not included in the response and how can I include it?

CSS files are not included in HTML.
They are downloaded by the browsers during HTML parsing.
Your example doesn't work because, when browser tries to get css/FrontPageCSS.css it obtains the HTML output because your server responds always with content of FrontPage.html file.
I suggest you to use some web framework as express: http://expressjs.com/en/index.html

Related

How to disable 'Let site view files?' message (when running locally)

I am looking for a way to disable the popup message which shows when using window.showDirectoryPicker. This page is served from localhost via WebView2 component in a WPF app.
<!DOCTYPE html>
<html>
<body>
<div class="fl" style="margin: 0 0 2rem 0"><button id="addToFolder">Give access to folder</button></div>
</body>
</html>
<script>
let directory;
document.getElementById('addToFolder').addEventListener('click', async () => {
try {
directory = await window.showDirectoryPicker({
startIn: 'desktop'
});
for await (const entry of directory.values()) {
let newEl = document.createElement('div');
newEl.innerHTML = `<strong>${entry.name}</strong> - ${entry.kind}`;
document.getElementById('folder-info').append(newEl);
}
} catch (e) {
console.log(e);
}
});
</script>
Note that I already have full file system access via the WPF app, so its not a security concern.

Why does my css code file have my html source when I open developers tool on google chrome?

I have the following problem when I run my web application, the HTML source code appears to be in the css file on chrome developers tool:
I have my HTML file called index.html and the following in the source.
<!DOCTYPE html>
<html>
<head>
<title>Node</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="style.css" rel="stylesheet" type="text/css" title="Default Styles"
media="screen">
</head>
<body>
<h1> Welcome to my first node.js Website </h1>
<h2> this is how you and where you do the mark up in node js</h2>
<!-- footer -->
<div class= "base">
<footer>
<nav>
</nav>
</footer>
</div>
</body>
</html>
And the following is my CSS file called style.css
html, body{
font-family: 'Open Sans', sans-serif;
font-size: 100%;
padding: 0;
margin: 0;
width: 100%;
background: skyblue;
color: #fff;
}
/*
footer
*/
.base{
height: 50px;
width: 100%;
background-color: black;
border-bottom: 1px solid rgba(221, 221, 221, 0.13);
bottom: 0%;
position: fixed;
}
when I run this code on the local server and opening the developer's tool on google chrome
I see that the HTML source code is in the CSS file.[![The CSS file now has the HTML source running on the local server][1]][1]
Here is my Node.js
// Load the http module to create an http server.
var http = require('http');
var fs = require('fs');
var server = http.createServer(function (request, response) {
console.log('request was made:' + request.url);
fs.readFile('index.html', function(err,data){
response.writeHead(200, {'Content-Type' : 'text/html'});
response.write(data);
response.end();
});
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8005);
// send a message on the terminal
console.log("Server running at http://127.0.0.1:8005/");
The problem is in your server request handler. You are manually sending index.html for every request made by the browser. When you navigate to http://127.0.0.1:8005/ your server sends index.html so far so good but then the browser sees <link href="style.css" rel="stylesheet" type="text/css" title="Default Styles" and asks for http://127.0.0.1:8005/style.css but your server returns again index.html that's why it receives the content of index.html as it where style.css. You need to filter your requests to the server in order to respond with the correct file. In your case it could be like:
// Load the http module to create an http server.
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(request, response) {
console.log('request was made:' + request.url);
switch (request.url) {
case '/':
fs.readFile('index.html', function(err, data) {
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.write(data);
response.end();
});
break;
case '/style.css':
fs.readFile('style.css', function(err, data) {
response.writeHead(200, {
'Content-Type': 'text/css'
});
response.write(data);
response.end();
});
break;
default:
response.end();
break;
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8005);
// send a message on the terminal
console.log("Server running at http://127.0.0.1:8005/");
Please note that this is a very basic server. It lacks error handling and is very hard to scale and maintain. Maybe you would like to try a node server framework like express

invoke node.js server-side service in angularjs. getting following error. Error: [$injector:nomod] Module ‘angularjsNodejsTutorial’ is not available

This is the error: Error: [$injector:modulerr] Failed to instantiate module angularjsNodejsTutorial due to:
Error: [$injector:nomod] Module ‘angularjsNodejsTutorial’ is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.” exception. from browser or postman when I hit localhost:3000/dirPath then I get the data back but not through this html file.
//here are the files: index.html, app.js(angularjs) and index.js(node)
//index.html
<!DOCTYPE html>
<html ng-app="angularjsNodejsTutorial">
<head>
<title>Integrating AngularJS with NodeJS</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<script src="../node_modules/angular-route/angular-route.min.js"></script>
</head>
<body >
<div ng-controller="myController">
<ul >
<li> The Files Are: {{data}}</li>
</ul>
</div>
<script src="../public/javascripts/app.js" type="text/javascript"></script>
<script src="../node_modules/angular-route/angular-route.js"></script>
</body>
</html>
//(AngularJS Client-Side)app.js
var app = angular.module('angularjsNodejsTutorial',['ngRoute']);
app.controller('myController', function($scope, $http) {
$scope.data = [];
var request = $http.get('/dirPath');
request.success(function(data) {
console.print("The files from this directory are:", data);
$scope.data = data;
});
request.error(function(data){
console.log('Error: ' + data);
});
});
//Server-side node.js index.js file
var express = require('express');
var router = express.Router();
var path = require('path');
/* GET home page. */
router.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname, '../', 'views', 'index.html'));
});
router.get("/dirPath", function(req, res) {
var fs = require("fs");
var dir = '/Users/swapnil/Documents/Test';
fileList = [];
var files = fs.readdirSync(dir);
for(var i in files){
if (!files.hasOwnProperty(i)) continue;
var name = dir+'/'+files[i];
if (!fs.statSync(name).isDirectory()){
fileList.push(name);
}
}
return res.send(fileList);
});
module.exports = router;
I think you are over thinking your route process, this will do the basics:
function config ($routeProvider, _) {
$routeProvider.
when('/Order', {
templateUrl: '../modern/sections/views/view.html',
controller: 'Controller as ctrl',
caseInsensitiveMatch: true,
resolve: {
data: function(Factory){
var view = window.location.href.match(/OrderID=(.*)#/) || 'undefined';
if(Id === 'undefined'){
return Factory.createOrder();
}else{
return Factory.currentOrder(OrderId[1]);
}
}
}
})
.otherwise({
redirectTo: '/'
});
}
FYI: Resolve calls Factories where i have services setup to get my API data.
Sorry if this is not direct, i copied this over from a current working project i have.
Resolved the issue by exposing the server side functionality as a RESTful API instead of node and modified my controller by adding appropriate header info for content type and implemented CORS filter on the server side.
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers",
"X-Requested-With,Origin,Content-Type, Accept");
filterChain.doFilter(request, response);
}
Thanks everyone for taking time to look at my issue and offering help. Appreciate.
Check your modules and make sure they are being loaded appropriately. It's a very common error when you start out. Check your html file and make sure all the modules names are spelled correctly.
If your modules are sharing logic it's common to accidentally miss spell the module name. This case I normally copy and past it over.
Also look at your logic behind the module and make sure you are declaring it properly.

HTML not Linking to CSS Properly

Html not properly loading css file.
Here is my html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<h1>TEST</h1>
</body>
</html>
and my style.css file is in the same folder as my .html file shown above.
Here is my style.css file:
body {
background: red;
}
When I inspect the "Network" tab of the Chrome developer tools, my style.css file is listed as "pending".
Any idea how to fix this? I have tried disabling AdBlock and clearing the cache.
My server is being run on node.js, not sure if that's relevant here...
Here is my server.js:
var http = require("http");
// server sends all requests to router file
var router = require("./router.js");
// set the port #
port = "8080";
// server to listen for requests
http.createServer(function (request, response) {
router.home(request, response);
}).listen(port);
// Console will print the message
console.log('Server running at http://127.0.0.1:' + port + '/');
and here is my router.js file:
var renderer = require("./renderer.js");
var url = require("url");
var htmlHeader = {'Content-Type': 'text/html'};
function home(request, response) {
if (request.url === "/") {
if (request.method.toLowerCase() === "get") {
response.writeHead(200, htmlHeader);
renderer.view("header", {}, response);
renderer.view("footer", {}, response);
response.end();
}
}
}
module.exports.home = home;
and finally the renderer.js file:
// to read contents of [view].html files
var fs = require('fs');
// insert contents into [view].html file
function mergeValues(values, content) {
// cycle over keys
for (var key in values) {
// replace all {{key}} with the value from the values object
content = content.replace("{{" + key + "}}", values[key]);
}
// return merged content
return content;
}
// handle the view passed as an argument
function view(templateName, values, response) {
// find the [view].html file in the /views/ folder
var fileContents = fs.readFileSync('./views/' + templateName + '.html', {encoding: "utf8"});
// insert values in to the content of the view file
fileContents = mergeValues(values, fileContents);
// write out contents to response
response.write(fileContents);
}
module.exports.view = view;
Thanks
As static files are requested just like any other HTTP request, the server will not locate your css file because you have no route for it.
You will need to add something like:
if (request.url === "/style.css") {
fs.readFile('style.css', function (err, data) {
response.writeHead(200, {'Content-Type': 'text/css', 'Content-Length': data.length});
response.write(data);
response.end();
});
}
There are of course better ways to serve static files with module that locates existing files automatically for you. This is ment as a simple answer only.
Have you privileges to access to the css file? Try:
chmod 777 style.css

Favicon.ico not being requested

Is there a way to setup an icon for an HTML page using only 'http' and 'fs' modules for node.js (without express)?
I have index.html, main_page.css and favicon.ico files in my directory.
When the client connects, it receives index.html:
<!DOCTYPE html>
<html>
<head>
<title>Site</title>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="css/main_page.css" />
</head>
<body>
</body>
</html>
Then the server receives a request for .css file and sends it to the client.
The page is styled as it should be, so there is no reason to show the code.
The question is, why does the client ask for .css file by itself and doesn't ask for .ico?
This is the code on the server, that serves the files:
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
switch (req.url) {
case '/': {
get_file('index.html', res);
break;
}
case '/css/main_page.css': {
get_file('css/main_page.css',res);
break;
}
case '/favicon.ico': {
get_file('favicon.ico', res);
break;
}
default: {
res.statusCode = 404;
res.end("Not found");
}
}
}).listen(8081);
function get_file(path, res) {
//dont mind my ROOT ;0
fs.readFile(ROOT + path, function(err, content) {
if(err) {
console.log(err.message);
} else {
console.log(path);
res.end(content);
}
})
}
The favicon.ico file gets cached by Chrome, so once it has been requested once, it will not be requested again until the cache expires. To generate a new request for favicon.ico you will need to refresh the page in Chrome.