I am trying to build a Node.js/AngularJS app with Openshift 2. The server is being run successfully and if I go to local adress I get index.html(but blank as it does not load the css), I cant get scripts and links on index.html, I get an error 404 but I dont know why.
Folder structure:
sw [sw master]
pages
index.html
inicio.html
css
inicio.css
js
angular.js
aplicacion.js
app.js
start.js
app.js
const http = require('http'),
fs = require('fs'),
path = require('path'),
contentTypes = require('./utils/content-types'),
sysInfo = require('./utils/sys-info'),
env = process.env;
let server = http.createServer(function (req, res) {
let url = req.url;
if (url == '/') {
url += '/index.html';
}
// IMPORTANT: Your application HAS to respond to GET /health with status 200
// for OpenShift health monitoring
if (url == '/health') {
res.writeHead(200);
res.end();
} else if (url == '/info/gen' || url == '/info/poll') {
res.setHeader('Content-Type', 'application/json');
res.setHeader('Cache-Control', 'no-cache, no-store');
res.end(JSON.stringify(sysInfo[url.slice(6)]()));
} else {
fs.readFile('./pages' + url, function (err, data) {
if (err) {
res.writeHead(404);
res.end('Not found');
} else {
let ext = path.extname(url).slice(1);
if (contentTypes[ext]) {
res.setHeader('Content-Type', contentTypes[ext]);
}
if (ext === 'html') {
res.setHeader('Cache-Control', 'no-cache, no-store');
}
res.end(data);
}
});
}
});
server.listen(env.NODE_PORT || 3000, env.NODE_IP || 'localhost', function () {
console.log(`Application worker ${process.pid} started...`);
});
index.html
<!DOCTYPE html>
<html lang="es" data-ng-app="TFG">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Página principal</title>
<script src="../js/angular.js"></script>
<script src="../js/app.js"></script>
<link href="../css/inicio.css" rel="stylesheet" />
</head>
<body>
<!--CUERPO-->
<div data-ng-view></div>
</body>
</html>
your index file should be at root level as you are providing path in your nodejs file.
Right now your index.html is under "pages" folder.
pages
index.html
inicio.html
I think this will be your tree
sw [sw master]
pages
inicio.html
css
inicio.css
js
angular.js
aplicacion.js
emphasized textindex.html
app.js
start.js
The Node.js script running the server will render html from page folder. This index.html has the css and js linked by relative path from the folder structure but you need to expose that publicly too to get reached by the browser when it tries to get the resources. You will need some code to serve that static content.
In fact, is your own code returning that 404 as the URL that the browser is trying to get the resources (css and js) from your pages folder and they are not found.
fs.readFile('./pages' + url, function (err, data) {
if (err) {
res.writeHead(404);
res.end('Not found');
}
You should include some code that return the css and js files.
Related
So I just made a HTML page added a script tag with src to a js file and sent the HTML file as response with node js using HTTP module.
But the js file is not working and when I checked the network tab I saw js file is received as text/html file.
Following are the js and html codes.
Server code with node js
const http = require('http') ;
const file = require('fs') ;
const server = http.createServer((req, res) => {
file.readFile('public/login.html', (err, data) => {
if (err) throw err ;
res.writeHead(200, {'Content-Type': 'text/html'}) ;
res.write(data) ;
res.end() ;
})
}) ;
server.listen(5000) ;
front end code : login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<script defer src="js/index.js"></script>
</head>
<body>
<h1>Login</h1>
<form action="" method="post">
<input type="email" name="user" id="user">
<input type="password" name="pass" id="pass">
<button type="submit" name="button" value="login">Login</button>
</form>
</body>
</html>
now when I load the page at localhost:5000, js does not execute and it's received as text/html.
The browser will receive the HTML, see the script tag, and request js/index.js from your server. But your server only sends your HTML file. It doesn't pay any attention to what the browser requested, it just always sends back the HTML. So the script is never sent to the browser, so the browser can't execute it.
Your server code needs to look at req to determine what was requested (looking at url, etc.), and send an appropriate response, rather than always sending back the same content.
Here's a fairly simple example that handles /, /login.html, and /js/index.js paths (making the first two synonyms):
const http = require('http');
const file = require('fs');
const FILENAME_404 = "public/404.html";
const server = http.createServer((req, res) => {
let filename = null;
let contentType = "text/html";
let status = 200;
// What did the browser ask for?
switch (req.url.toLowerCase()) {
case "/":
case "/login.html":
// The login page
filename = "public/login.html";
break;
case "/js/index.js":
// The JavaScript file
filename = "public/js/index.js";
contentType = "text/javascript";
break;
default:
// Something we don't support -- send a 404
filename = FILENAME_404;
status = 404;
break;
}
sendFile(res, filename, contentType, status);
});
function sendFile(res, filename, contentType, status, callback) {
file.readFile(filename, (err, data) => {
if (err) {
// Couldn't read the file, send a 404
if (filename !== FILENAME_404) {
sendFile(res, FILENAME_404, "text/html", 404);
} else {
// Couldn't even find the 404 file, send a minimal plaintext 404
res.writeHead(404, {"Content-Type": "text/plain"});
res.write("The requested resource does not exist on this server.");
res.end();
}
} else {
res.writeHead(status, {"Content-Type": contentType});
res.write(data);
res.end();
}
});
}
server.listen(5000);
Note: This is just an example. If you're going to build anything of any size, you'll want more structure than this. You might look at Express or Koa or others that handle more of the HTTP plumbing, URL routing, etc. for you and have modules available for other things as well.
My File Structure -
> client-
> -app.js
> index.html
> require.js
> server.js
server.js - to create a basic http server
const http = require('http'),
fs = require('fs');
function send404(response) {
response.writeHead(404, {'Content-Type': 'text/plain'});
response.write('Error 404: Resource not found.');
response.end();
}
const server = http.createServer( (req,res) => {
if(req.method == 'GET' && req.url == '/')
{
res.writeHead(200, {'content-type': 'text/html'});
fs.createReadStream('index.html').pipe(res);
}
else
{
send404(res);
}
}).listen(3000);
console.log('server running on port 3000');```
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">
<title>Hello There</title>
<script
src="require.js"
data-main="client/app.js">
</script>
</head>
<body>
<p>Press Ctrl + Shift + J (windows) or CMD + Opt + J (MacOSX) to open up the console.</p>
</body>
</html>
```
app.js
console.log('Hello RequireJS!');
I am supposed to get Hello RequireJS! as output in the chrome developer tools console.
But, i get 3 errors as shown below:
1.
Denying load of
chrome-extension://laankejkbhbdhmipfmgcngdelahlfoji/app.js. Resources
must be listed in the web_accessible_resources manifest key in order
to be loaded by pages outside the extension.
2.
GET http://localhost:3000/require.js net::ERR_ABORTED 404 (Not Found)
3.
GET chrome-extension://invalid/ net::ERR_FAILED
Please tell me if you have also encountered this problem and how to solve this.
Thanks.
`
server.js:
var http = require('http');
var fs = require('fs');
function onRequest(request,response){
response.writeHead(200, {'content-Type':'text/html'});
fs.readFile('./index.html',null,function(error,data){
if(error)
{
response.writeHead(404);
response.write('File not found');
}
else
{
response.write(data);
}
response.end();
});
fs.readFile('./about.html',null,function(error,data){
if(error)
{
response.writeHead(404);
response.write('File not found');
}
else
{
response.write(data);
}
response.end();
});
}
http.createServer(onRequest).listen(8080);
I am new in Node.js where I have created a simple HTML page i.e. index.html and about.html inside the folder. I had also created a server.js.
Now, when I run a command on cmd and run on localhost:8080 then index.html page are showing but when I click on hyperlink i.e. then it not working.
So, How can I create a hyperlink in node js?
To render different html files you have to use url-based redirect. I have used your example to make it more clear.
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
go to about
</body>
</html>
about.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
go to index
</body>
</html>
server.js
var http = require('http');
var fs = require('fs');
function onRequest(request,response){
response.writeHead(200, {'content-Type':'text/html'});
if(request.url=='/' || request.url=='/index.html'){
fs.readFile('./index.html',null,function(error,data){
if(error)
{
response.writeHead(404);
response.write('File not found');
}
else
{
response.write(data);
}
response.end();
});
}
if(request.url=='/about.html'){
fs.readFile('./about.html',null,function(error,data){
if(error)
{
response.writeHead(404);
response.write('File not found');
}
else
{
response.write(data);
}
response.end();
});
}
}
http.createServer(onRequest).listen(8080);
To serve static files in express you need to configure the middleware with express.static, like this:
app.use('/', express.static('html'));
This way, if you have all your html files inside the html folder, express will map the / to where your html files are.
Just remembering, the path '/' is relative from where you start your node process.
This question already has answers here:
How to serve an image using nodejs
(12 answers)
Closed 5 years ago.
Good day ,
I've got a small problem with my NodeJS http server. The server doesn't load the CSS/JS files from folder , only from url and i don't know why. I would appreciate if someone could take some time and give me some tips on what went wrong.
Here is the Server Code :
var http = require("http");
var gs = require("querystring");
var url = require("url");
var fs = require("fs");
var server = http.createServer(function (request, response, err) {
//HTML
if (request.url === "/") {
sendFileContent(response, "HTML/Login.html", "text/html");
console.log("Requested URL : " + request.url + "\n");
}
else if (request.url === "/main") {
sendFileContent(response, "HTML/Main_Home.html", "text/html");
console.log("Requested URL : " + request.url + "\n");
}
// JS / CSS / Other formats
else if (/^\/[a-zA-Z0-9\/]*.js$/.test(request.url.toString(1))) {
sendFileContent(response, request.url.toString().substring(1), "text/javascript");
}
else if (/^\/[a-zA-Z0-9\/]*.css$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "text/css");
}
else if (/^\/[a-zA-Z0-9\/]*.json$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "application/json");
}
else if (/^\/[a-zA-Z0-9\/]*.ts$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "text/javascript");
}
else if (/^\/[a-zA-Z0-9\/]*.png$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "image/png");
}
else if (/^\/[a-zA-Z0-9\/]*.jpg$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "image/jpeg");
}
else
{
console.log("Requested URL : " + request.url + "\n");
response.end();
}
});
server.listen(1337, function ()
{
require("console-stamp")(console, '[HH:MM:ss]');
console.log("HTTP Server runs on port : 1337");
});
console.log("Server ready....");
And here is the Send file content function :
function sendFileContent(response, fileName, contentType){
fs.readFile(fileName, function (err, data) {
if (err) {
response.writeHead(404);
response.end("Not Found!");
}
else {
response.writeHead(200, { "Content-Type": contentType });
response.end(data);
}
});
};
And this is how i call the files in html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="../materialize/css/materialize.min.css" media="screen,projection" />
<link type="text/css" rel="stylesheet" href="../CSS/App.css" />
<title></title>
<script type="text/javascript" src="../jquery/jquery-3.2.0.min.js"></script>
<script type="text/javascript" src="../materialize/js/materialize.min.js"> </script>
<script type="text/javascript" src="../Javascript/Main_App.js"></script>
Thank you for your time !
You are trying to implement your own static files server and there so many problems in your implementation even besides those that you're asking about that I think that you need to rethink your approach.
To serve static files it is much easier to use a working solution like express.static - but read below for solutions without Express if you really need it. Example with express.static:
var path = require('path');
var express = require('express');
var app = express();
var dir = path.join(__dirname, 'public');
app.use(express.static(dir));
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
See this answer for more options using connect, express, http and net:
How to serve an image using nodejs
In that answer there are examples of doing what you're trying to do here using express.static, Express without express.static, using connect, using http and using net and even the version that uses raw TCP sockets is not as complicated as your code here. You may want to take a look at it and base your code on these examples.
I'm trying to write my first Nodejs server for getting to know Angular/Node and eventually the whole MEAN stack.
My server is running but there's a problem in my code, for some reason when I enter a non existing file, it should redirect to 404, but it doesn't. For some reason the URL gets a double dash;
How would I go about making the redirect to 404 work?
check this image
Here is my code for the server so far.
var http = require('http'),
fs = require('fs'),
path = require('path'),
root = __dirname + '/public/', //magic var
mime = require('mime');
//Server
var server = http.createServer(function (req, res) {
// Check is root is queried
var fileName = '';
var url = req.url;
if (url === '/'){
url = 'index.html'; // redirect when no file specified
}
fileName = root + url;
// check if file exists
fs.exists(fileName, function(exists){
if (exists) {
serveFile(fileName); // yes
} else {
path = root + '404.html'; //no
serveFile(fileName);
}
})
//serve file
function serveFile(requestFile) {
// maak a stream based on events
var stream = fs.createReadStream(requestFile);
res.writeHead(200, {'Content-Type': mime.lookup(requestFile)});
stream.on('data', function (chunk){
res.write(chunk);
});
stream.on('end', function(){
res.end();
});
stream.on('error', function(err){
console.log('error: '+ err);
});
}
});
server.listen(3000); //server start
console.log('Server gestart op http://localhost:3000 ');
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>angular</title>
<link href="https://cdn.jsdelivr.net/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="styles/app.css" rel="stylesheet"/>
</head>
<body ng-app class="bg">
<h1>First name?</h1>
<input type="text" placeholder="Type your name" ng-model='firstName'
class="input-lg"/>
<p>
Hi, {{firstName}}
</p>
<img src="https://static.pexels.com/photos/7720/night-animal-dog-pet.jpg" height="100px" width="100px"/>
</body>
<script type="text/javascript" src="https://cdn.jsdelivr.net/angularjs/1.5.5/angular.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/angularjs/1.5.5/angular.min.js"></script>
</html>
Could anyone tell me what's going wrong here?
Thanks in advance!
get rid of the '/' after public:
root = __dirname + '/public'
It is the default behaviour of Node JS. ie. If you request for xxx.com/sample.txt, then the req.url will be "/sample.txt".
https://nodejs.org/api/http.html#http_message_url
So you have consider that in your code, as #Jordan mentioned, remove the "/".
Your redirect also should work fine.