I cant get the contents included in the head of the served defualt.htm page to "work". The html loads in the dom, just the CSS and JS files fail. Is there a better alternative? Id like to keep the solution within NodeJS but alternatively open to socket.io and express as well.
Thanks, below is what im using.
NodeJS Serving the Page
var http = require('http'),
fs = require('fs');
fs.readFile(__dirname+'/default.htm', function (err, html) {
if (err) {
throw err;
}
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(port.number);
});
Default.html Page
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="objects/css/site.css" type="text/css" />
<script src="objects/js/jquery.min.js" type="text/javascript"></script>
<script src="objects/js/site.min.js" type="text/javascript"></script>
</head>
<body></body>
</html>
I cant get the contents included in the head of the served defualt.htm page to "work". The html loads in the dom, just the CSS and JS files fail. Is there a better alternative? Id like to keep the solution within NodeJS but alternatively open to socket.io and express as well.
Thanks, below is what im using.
NodeJS Serving the Page
var http = require('http'),
fs = require('fs');
fs.readFile(__dirname+'/default.htm', function (err, html) {
if (err) {
throw err;
}
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(port.number);
});
Default.html Page
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="objects/css/site.css" type="text/css" />
<script src="objects/js/jquery.min.js" type="text/javascript"></script>
<script src="objects/js/site.min.js" type="text/javascript"></script>
</head>
<body></body>
</html>
Share
Improve this question
edited Nov 12, 2012 at 7:03
sia
asked Nov 12, 2012 at 6:58
siasia
2,2154 gold badges21 silver badges17 bronze badges
2
- If you wanna write it yourself, check out github.com/felixge/node-paperboy or github.com/visionmedia/send module for nodejs. They can help you with delivering static files like css/js and images. – Henrik Andersson Commented Nov 12, 2012 at 7:22
- My question is, why are you serving static files with node.js? use nginx or similar. All not user-facing tasks shouldn't be done in the same event loop that you use to serve dynamic content. – Gabriel Llamas Commented Nov 12, 2012 at 9:18
5 Answers
Reset to default 4Your Javascript and styles are failing because they don't exist. Your current webserver is only sending a single route, the root route. Instead you'll need to allow the use of multiple routes. ExpressJS does this for you in a simpler way, but still very possible without it.
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(request, response){
var header_type = "";
var data = "";
var get = function (uri, callback) {
// match `request.url` with uri with a regex or something.
var regex = uri;
if (request.url.match(regex)) {
callback();
}
};
var render = function (resource) {
// resource = name of resource (i.e. index, site.min, jquery.min)
fs.readFile( __dirname + "/" + resource, function(err, file) {
if (err) return false; // Do something with the error....
header_type = ""; // Do some checking to find out what header type you must send.
data = file;
}
};
get('/', function(req, res, next) {
// Send out the index.html
render('index.html');
next();
});
get('/javascript.min', function(req, res, next) {
render('javascript.js');
next();
});
});
server.listen(8080);
This might get you started, but you'll have to implement some things like next()
yourself. A pretty simple solution, but a working one.
Another solution for responding to static files would be to create a catcher within the http.createServer
callback. Within the get
method, if the uris don't match, then you would look within a public
folder matching the full uri to the file system structure.
I'm going to throw my two cents in here as well.
The way I solved the same problem with serving static files is that I started using the Paperboy module, which is deprecated in favor of the Send module nowadays.
Anyhoo, the way I solved it was to "hijack" the request before it went into my GET method and check the path of it.
The way I "hijack it" is as follows
self.preProcess(self, request, response);
and
preProcess: function onRequest(app, request, response){ //DO STUFF }
If the path contained the STATICFILES dir, I would do a diffrent serving of files otherwise I'd go with the "html"-path. Below is the //DO STUFF
of the preProcess()
function
var path = urllib.parse(request.url).pathname;
if(path.indexOf(settings.STATICFILES_DIR) != -1) {
path = settings.STATICFILES_DIR;
requestedFile = request.url.substring(request.url.lastIndexOf('/') + 1, request.url.length);
return resolver.resolveResourceOr404(requestedFile, request, response);
}
There might be a better way of doing this but this works like a charm for the things that I need it to do.
Using the Paperboy module I then, using the resolver.resolveResourceOr404();
function
deliver the file like so
resolveResourceOr404 : function (filename, httpRequest, httpResponse) {
var root = path.join(path.dirname(__filename), '');
paperboy.deliver(root, httpRequest, httpResponse)
.error(function(e){
this.raise500(httpResponse);
})
.otherwise(function(){
this.raise404(httpResponse);
});
}
Well, you are serving your default.htm
file on all requests. So, when the browser asks for objects/js/jquery.min.js
, your server returns the contents of default.htm
.
You should really consider using express or some other framework.
what about trying this:
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function (request, response) {
console.log('request starting...');
var filePath = '.' + request.url;
if (filePath == './')
filePath = './index.html';
var extname = path.extname(filePath);
var contentType = 'text/html';
switch (extname) {
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
case '.json':
contentType = 'application/json';
break;
case '.png':
contentType = 'image/png';
break;
case '.jpg':
contentType = 'image/jpg';
break;
case '.wav':
contentType = 'audio/wav';
break;
}
fs.readFile(filePath, function(error, content) {
if (error) {
if(error.code == 'ENOENT'){
fs.readFile('./404.html', function(error, content) {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
});
}
else {
response.writeHead(500);
response.end('Sorry, check with the site admin for error: '+error.code+' ..\n');
response.end();
}
}
else {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
}
});
}).listen(8125);
console.log('Server running at http://127.0.0.1:8125/');
You're better off with using Express for this kind of stuff.
Something like this will do the job.
App.js
var express = require('express')
, http = require('http')
, path = require('path');
var app = express();
//Configure Your App and Static Stuff Like Scripts Css
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views'); // Your view folder
app.set('view engine', 'jade'); //Use jade as view template engine
// app.set("view options", {layout: false});
// app.engine('html', require('ejs').renderFile); //Use ejs as view template engine
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public')); //Use Stylus as the CSS template engine
app.use(express.static(path.join(__dirname, 'public'))); //This is the place for your static stuff
});
app.get('/',function(req,res){
res.render('index.jade',{
title:"Index Page
}
});
Index is a jade template page.Which renders into static html and works pretty good with express.
For a global static header to all of your pages you can make a template like this and include it in any.
static_header.jade
doctype 5
html
head
title= title
script(src='/javascripts/jquery-1.8.2.min.js')
block header
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
And finally your index.jade which is using the static_header and own dynamic header with its own scripts.
extends static_header
block header
script(src='/javascripts/jquery-ui-1.9.1.custom.js')
script(src='http://jquery-ui.googlecode.com/svn/trunk/ui/i18n/jquery.ui.datepicker-tr.js')
link(rel='stylesheet',href='/stylesheets/jquery-ui-1.9.1.custom.min.css')
block content
h1= title
Put both of the files in your views folder and ready to roll.