javascriptnode.jsview-source

Node.js View Source Breaks Filesystem Module


I am trying to create a web server in node.js, but I have run into a weird problem.

The server responds correctly to a request to view the page, but when I view the page source on some browsers, the node server throws the error

fs.js:379
  binding.open(pathModule.toNamespacedPath(path),
          ^

TypeError: path must be a string or Buffer
    at Object.fs.readFile (fs.js:379:11)
    at Server.<anonymous> (/ProjectFolder/index.js:32:6)
    at Server.emit (events.js:180:13)
    at parserOnIncoming (_http_server.js:642:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:117:17)

I thought, maybe the request to view source has a weird request path, but a) it said TypeError, so it would have err'd in the resolveFileName function. And b) wouldn't the view source just display the request result differently in the client side, not making any changes to the request?

Google chrome: Error
MS Edge: OK
Internet Explorer: Error
Netscape 8: OK

Here is my code:

Filesystem:

> ProjectFolder
| > index.js
| > svrpath
| | > file.html

index.js:

var http = require('http');
var fs = require('fs');

function resolveFileName(req){
  var typs = {
    ".html": "text/html",
    ".css": "text/css",
    ".js": "text/javascript"
  };
  if(req === "/"){
    return {
      fname: "./svrpath/file.html",
      type: "text/html"
    };
  }else if(/^.*\.(html|css|js)$/.test(req)){
    return {
      fname: "./svrpath" + req,
      type: typs[req.replace(/^.*(?=\.(html|css|js)$)/, "")]
    };
  }else if(/^.*\/$/.test(req)){
    return {
      fname:"./svrpath" + req.replace(/\/$/, "") + ".html",
      type: "text/html"
    };
  }else{
    return "error400";
  }
}

http.createServer(function(req, res){
  var file = resolveFileName(req.url);
  fs.readFile(file.fname, function(err, data){
    if(err){
      throw err;
    }
    res.writeHead(200, {"Content-Type": file.type});
    res.end(data);
  });
}).listen();

svrpath/file.html

<!DOCTYPE html>
<html>
  <body>
    <p>Hello World!</p>
    <p>Some more content</p>
  </body>
</html>

Working Example


Solution

  • Your browser default asking for favicon.ico, you have no answer for this, thats why you have undefined path (no this case). You can add file favicon.ico and create condition for it:

    function resolveFileName(req){
      var typs = {
        ".html": "text/html",
        ".css": "text/css",
        ".js": "text/javascript"
      };
      if(req === "/"){
        return {
          fname: "./svrpath/file.html",
          type: "text/html"
        };
      }else if(/^.*\.(html|css|js)$/.test(req)){
        return {
          fname: "./svrpath" + req,
          type: typs[req.replace(/^.*(?=\.(html|css|js)$)/, "")]
        };
      }else if(/^.*\/$/.test(req)){
        return {
          fname:"./svrpath" + req.replace(/\/$/, "") + ".html",
          type: "text/html"
        };
      }else if(req === "/favicon.ico"){
          return {
            fname: "./svrpath/favicon.ico",
            type: "image/x-icon"
          }
      }else{
        return "error400";
      }
    }