Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js + Serve Static Files with RESTIFY

I have a multi-level collection of .html, .js, .png, .css, etc files in a site. A peek at my site hiearchy looks like the following:

index.html
child1
  index.html
  page1.html
  page2.html
  ...
child2
  grandchild1
    index.html
  grandchild2
    index.html
  index.html
  page1.html
  page2.html
resources
  css
    myTheme.css
  img 
    logo.png
    profile.png
  js
    jquery.js
    ...
...

I am migrating this to run under Node.js. I have been told I MUST use RESTIFY. Currently, I've written the following for my server:

var restify = require('restify');
var fs = require('fs');
var mime = require('mime');

var server = restify.createServer({
    name: 'Demo',
    version: '1.0.0'
});

server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());

server.get('/', loadStaticFile);

server.get('/echo/:name', function (req, res, next) {
    res.send(req.params);
    return next();
});

server.listen(2000, function () {
    console.log('Server Started');
});

function loadStaticFile(req, res, next) {
    var filePath = __dirname + getFileName(req);
    console.log("Returning " + filePath);

    fs.readFile(filePath, function(err, data) {
      if (err) {
        res.writeHead(500);
        res.end("");
        next(err);
        return;
      }

      res.contentType = mime.lookup(filename);
      res.writeHead(200);
      res.end(data);

      return next();
    });
}

function getFileName(req) {
    var filename = "";
    if (req.url.indexOf("/") == (req.url.length-1)) {
      filename = req.url + "index.html";
    } else {
      console.log("What Now?");
    }
    return filename;
}

With this code, I can successfully load index.html. However, my index.html file references some JavaScript, image files, and style sheets. I can see via Fiddler that that these files are being requested. However, in my node.js console window, I never see "Returing [js|css|png filename]". Its like my node.js web server returns index.html and that's it.

What am I doing wrong?

like image 237
user2871401 Avatar asked Oct 11 '13 14:10

user2871401


People also ask

How do I serve a static file in node?

In your node application, you can use node-static module to serve static resources. The node-static module is an HTTP static-file server module with built-in caching. First of all, install node-static module using NPM as below. After installing node-static module, you can create static file server in Node.

What is Restify in node js?

restify is a node. js module purpose built to create REST web services in Node. restify makes lots of the hard problems of building such a service, like versioning, error handling and content-negotiation easier.

What is Restify server?

A restify server object is the main interface through which you will register routes and handlers for incoming requests.

What are static files in node js?

Static files are typically files such as scripts, CSS files, images, etc... that aren't server-generated, but must be sent to the browser when requested. If node. js is your web server, it does not serve any static files by default, you must configure it to serve the static content you want it to serve.


2 Answers

The latest versions of restify has builtin middleware serveStatic() middleware that will do this for you.

from a http://mcavage.me/node-restify/#Server-API

server.get(/\/docs\/public\/?.*/, restify.serveStatic({
  directory: './public'
}));

for more detailed example:

http://mushfiq.me/2013/11/02/serving-static-files-using-restify/

like image 127
Calvin Alvin Avatar answered Oct 25 '22 21:10

Calvin Alvin


Do any of your served files contain relative paths (say ../abc.js)? You have to use path.resolve() to get the real path for fs.readFile().

Anyway there are a lot of pitfalls in serving files:

  • invalid url (400)
  • file not found (404)
  • escape sequence (url encoding)
  • fs.read() read files into memory (by @robertklep)
  • etc

You can use existing static file serving middleware.
I've been using Ecstatic, AFAIK it handles those issues properly.

Try

server.use(ecstatic({ root: __dirname + '/' }));

If that fails you can refer to this to stack Restify on top of Connect/Express.

like image 24
leesei Avatar answered Oct 25 '22 21:10

leesei