无法调用方法' toString'在javascript中的null - nodejs

时间:2017-09-11 00:18:26

标签: javascript node.js

我是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)。

我仍然不清楚为什么会这样。经过一番研究,我发现为了调用闭包函数,我应该保存"这个"指向成员变量的指针。另外,实例会有所不同。 但是,这还没有解决问题。 此外,欢迎任何设计缺陷或评论。

enter image description here

这是我的代码 -

主文件 -

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;

1 个答案:

答案 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