我是JS新手并尝试编写一个简单的网络服务器。这是我的prj浏览器。 当我进入浏览器 - http://localhost:4000/home.html
时我收到错误 - 无法调用方法' toString' null。
问题是UrlResLoader.httpcode和UrlResLoader.fileType没有定义
var UrlResLoader = new UrlLoader();
UrlResLoader.requestUrl(fileResEngine);
res.writeHead(UrlResLoader.httpcode, UrlResLoader.fileType);
res.write(UrlResLoader.data);
res.end()
我不知道这里有什么问题,我已经挂了一个调试器,发现问题发生在fs.readFile(fileResEngine.fullpath,function(err,data)。
我仍然不清楚为什么会这样。经过一番研究,我发现为了调用闭包函数,我应该保存"这个"指向成员变量的指针。另外,实例会有所不同。 但是,这还没有解决问题。 此外,欢迎任何设计缺陷或评论。
这是我的代码 -
主文件 -
const http = require('http');
const parseUrl = require('parseurl');
const fileEngine = require('./fileErrHandler');
const UrlLoader = require('./urlController');
http.createServer( function (req, res)
{
try
{
// this is a library function
var pathName = decodeURIComponent(parseUrl(req).pathname);
var fileResEngine= new fileEngine(pathName);
// create a literal validateFile to validate the 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);
文件错误处理程序
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 the 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;
最终文件
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;
答案 0 :(得分:1)
首先,这是错误的:
var pathName = decodeURIComponent(parseUrl(req).pathname);
这可能是您pathName
后来出错的原因。 req
是一个请求对象,它不是您可以解析的URL。 URL路径位于该请求对象中。 req.url
将包含请求路径(没有域。端口和协议 - 只是路径)。
所以,将上面的行改为:
var pathName = decodeURIComponent(req.url);
我无法保证该代码块中没有其他错误(我根本不知道fileEngine
模块),但这至少是一回事清除会影响您的pathName
错误,从而导致您在尝试使用pathName
时遇到的错误。
现在你已经解决了这个问题,看来你也遇到了异步问题。您已对UrlController.requestUrl
进行了编码,但未编码任何方式以了解其异步工作何时完成。它立即返回,然后在某个时间之后,它内部的fs.readFile()
结束。因此,您最终会在设置之前尝试使用对象的属性。
您需要使用promises或回调来让调用者知道异步操作何时实际完成。我建议您阅读有关返回异步数据主题的canonical answer。