node.js - Cannot call method 'toString' of null in javascript - nodejs -
i new js , trying write simple webserver. here prj browser. when go browser -http://localhost:4000/home.html
i error - cannot call method 'tostring' of null.
the problem urlresloader.httpcode , urlresloader.filetype isn't defined
var urlresloader = new urlloader(); urlresloader.requesturl(fileresengine); res.writehead(urlresloader.httpcode, urlresloader.filetype); res.write(urlresloader.data); res.end()
i not sure problem here, have hooked debugger , have found problem happens on fs.readfile(fileresengine.fullpath, function (err, data).
i still unclear on why happening. after researching bit, found inorder invoke closure functions, should save "this" pointer refer member varaibles. other wise, instance different. but, hasn't fixed problem. also, design flaws or comments welcomed here.
here code -
the main file -
const http = require('http'); const parseurl = require('parseurl'); const fileengine = require('./fileerrhandler'); const urlloader = require('./urlcontroller'); http.createserver( function (req, res) { try { // library function var pathname = decodeuricomponent(parseurl(req).pathname); var fileresengine= new fileengine(pathname); // create literal validatefile validate path fileresengine.pathcheck(); if (fileresengine.error === true ) { res.statuscode = fileresengine.statuscode; res.end(fileresengine.errormsg); return; } else { var urlresloader = new urlloader(); urlresloader.requesturl(fileresengine); res.writehead(urlresloader.httpcode, urlresloader.filetype); res.write(urlresloader.data); res.end(); } } catch(err) { res.statuscode = err.status || 500; res.end(err.message); } }).listen(4000);
the file error handler
var resolvepath = require('resolve-path'); const path = require('path'); var pagesdir = path.join(__dirname, 'pages'); function pathcheckerengine(path) { this.error = true; this.path = path; this.statuscode = 500; this.errormsg = "internal server error"; this.pagerequest = "home.html"; this.extname = "html"; this.fullpath = './'; var pcengine = this; this.pathcheck = function() { try { if (!path) { pcengine.statuscode = 400; pcengine.errormsg = 'path required'; pcengine.error = true; } else { //removes first '/' of path pcengine.pagerequest = path.substr(1); pcengine.fullpath = resolvepath(pagesdir, this.pagerequest); pcengine.statuscode = 200; pcengine.errormsg = null; pcengine.error = false; pcengine.extname = this.pagerequest.split('.').pop(); } } catch(err) { pcengine.statuscode = err.status || 500; pcengine.errormsg = 'malicious page request'; pcengine.error = true; } } } module.exports = pathcheckerengine;
and final file
const fileengine = require('./fileerrhandler'); const fs = require('fs'); const mime = require('mime'); function urlcontroller(fileresengine) { this.httpcode = null; this.filetype = null; this.data = null; var urctrl = this; this.requesturl = function (fileresengine) { switch (fileresengine.extname) { case 'html': fs.readfile(fileresengine.fullpath, function (err, data) { if (err) { console.log(err); urctrl.httpcode = 404; urctrl.data = "page not found"; return; } urctrl.httpcode = 200; urctrl.filetype = "'content-type': 'text/html'"; urctrl.data = data; }); break; case 'png': case 'jpeg': case 'jpg': case 'bmp': fs.readfile(fileresengine.fullpath, function (err, data) { if (err) { console.log(err); urctrl.httpcode = 404; urctrl.data = "file not found"; return; } urctrl.httpcode = 200; urctrl.filetype = mime.lookup(mime.lookup('./images' + req.url)); urctrl.data = data; }); break; default: urctrl.httpcode = 404; urctrl.data = "page not found" break; } } return; } module.exports = urlcontroller;
for starters, wrong:
var pathname = decodeuricomponent(parseurl(req).pathname);
which why pathname
later on wrong. req
request object, it's not url can parse. url path in request object. req.url
contain request path (without domain. port , protocol - path).
so, change above line this:
var pathname = decodeuricomponent(req.url);
i can't promise there aren't other errors in block of code (i don't know fileengine
module @ all), @ least 1 thing clear affects pathname
being wrong can lead error later on when trying use pathname
.
now you've fixed that, appears have asynchronous problems. you've coded urlcontroller.requesturl
, not coded way know when done asynchronous work. returns right away , sometime later, fs.readfile()
inside of finishes. end trying use properties of object long before have been set.
you need use either promises or callback let caller know when asynchronous operations done. i'd suggest read canonical answer on topic of returning async data.
Comments
Post a Comment