簡體   English   中英

無法使用Node.js的“ http”模塊提供html文件

[英]Unable to serve html file using 'http' module of Node.js

我正在嘗試將html頁面作為對我的http服務器上的“ /”請求的響應。 但是不知何故,它不起作用。

我的index.html是-

<html>
<head>
    <title>File Explorer</title>
    <link rel='stylesheet' href='/stylesheets/style.css'/>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css"/>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.js"></script>

</head>

<script>
    var fileExplorerApp = angular.module('explorerApp', []);
    fileExplorerApp.controller("MyController", function ($scope, $http) {
        var currentPath = '';
        $scope.reload = function (newPath, back) {
            if (back) {
                currentPath = newPath;
            } else {
                if (currentPath === '') {
                    currentPath = newPath;
                } else {
                    currentPath = currentPath + '/' + newPath;
                }
            }
            console.log('Newpath- ' + currentPath);
            $http.get('http://localhost:3000/list_dir?path=' + currentPath)
                .then(function (response) {
                    $scope.filesAndFolders = response.data;
                    $scope.currentPath = currentPath;
                }, function (error) {
                    console.log('Error in $http- ' + error);
                });    
        }

        $scope.back = function () {
            var prevPath = currentPath.substring(0, currentPath.lastIndexOf('/'));
            console.log('Path after substring- ' + prevPath);
            console.log('Prevpath when back clicked- ' + prevPath);
            $scope.reload(prevPath, true);

        }

        $scope.reload('F:/', false);
    });
</script>

<body ng-app="explorerApp" ng-controller="MyController">

<div class="ui container">
    <h1 id="currentPath">Current Directory- {{ currentPath }}</h1>
    <button ng-if="currentPath !== 'F:/'"
            ng-click="back()"
            class="ui left labeled icon button">
        <i class="left arrow icon"></i>
        Back
    </button>
    <div class="ui list">
        <a class="item"
           ng-repeat="item in filesAndFolders"
           ng-click="reload(item.name, false)"
           ng-href="{{item.type === 'file' ? '/get_file?path='+currentPath+'/'+item.name : ''}}">
            <i ng-if="item.type === 'folder'" class="folder icon"></i>
            <i ng-if="item.type === 'file'" class="file icon"></i>
            {{ item.name }}</a>
    </div>
</div>
</body>
</html>

通過角度我訪問另一個路由'/ list_dir'並使用Node.js(Not Express)的'http'模塊處理請求。

if(parsedUrl.pathname === '/list_dir') {
            console.log('I\'m here');
            var file_path = parsedUrl.query['path'];
            list_dir.listDir(file_path, function (err, data) {
                if(err){
                    res.writeHeader(400, {'Content-Type':'text/json'});
                    res.write(err);
                } else {
                    console.log('in list_dir, no errors- response is- '+data);
                    res.writeHeader(200,{'Contenttype':'application/json'});
                    res.write(JSON.stringify(data));
                }
            });
            res.end();
            break;
        }

然后,路由“ / list_dir”訪問另一個腳本中的函數,該腳本為:

module.exports = {
listDir: function (path, myCallback) {
    var resultObj = [];

    fs.readdir(path, function (err, data) {
        console.log('In listDir');
        if (err) {
            switch(err.code){
                case 'EACCES':
                    return myCallback({errno: err.errno, description: 'An attempt was made to access a file in a way forbidden by its file access permissions.'}, null);
                case 'ENOENT':
                    return myCallback({errno: err.errno, description: 'The specified path does not exist.'});
                case 'EPERM':
                    return myCallback({errno: err.errno, description: 'An attempt was made to perform an operation that requires elevated privileges.'})
                case 'ENOTDIR':
                    return myCallback({errno: err.errno, description: 'The specified path is not a directory.'})
            }
            return myCallback(err, null);
        }

        var itemsCompleted = 0;
        data.forEach(function (value) {
            fs.lstat(path + '/' + value, function (err, stats) {
                itemsCompleted++;
                if (err) {
                    console.log(err);
                } else {
                    if (stats.isFile()) {
                        resultObj.push({
                            type: 'file',
                            name: value,
                            size: stats['size']
                        });
                        //resultObj.push(value);
                        //console.log(resultObj + '\n');
                    } else if (stats.isDirectory()) {
                        resultObj.push({
                            type: 'folder',
                            name: value,
                            size: stats['size']
                        });
                    }
                }

                if (itemsCompleted >= data.length) {
                    //console.log(resultObj);
                    return myCallback(null, resultObj)
                }
            });
        });
    });
}

};

此函數返回給定路徑內所有文件/文件夾的json對象,該對象將提供給'/ list_dir'路由。 但是我沒有從路線中得到正確的答復。

我希望此路由以listDir函數返回的相同json進行響應。 我是Node.js的http模塊的新手,可能是我把標頭寫錯了,還是我以錯誤的方式使用了數據。 請幫忙。 謝謝!

更新:

Chirags的回答是正確的,現在'/ list_dir'路由返回了正確的json響應。 但是,我仍然無法在使用AngularJS使用此路由的地方提供index.html文件。

這就是我處理路線的方式-

if (parsedUrl.pathname === '/') {
    fs.readFile('./index.html', 'utf-8', function (err, fileResponse) {
        if (err) {
            console.log('Error');
            res.writeHeader(404, {
                "Content-Type": "text/html"
            });
            res.write('There was an error!');
        } else {
            console.log('No error');
            res.writeHeader(200, {
                "Content-Type": "text/html"
            });
            res.write(fileResponse);
        }
        res.end();
    });
}

這怎么了

您太早關閉響應流。 基本上,在執行讀取目錄的異步函數並調用回調之前,將先執行res.end() 嘗試:

if (parsedUrl.pathname === '/list_dir') {
    console.log('I\'m here');
    var file_path = parsedUrl.query['path'];
    list_dir.listDir(file_path, function (err, data) {
        if (err) {
            res.writeHeader(400, {
                'Content-Type': 'text/json'
            });
            res.write(err);
        } else {
            console.log('in list_dir, no errors- response is- ' + data);
            res.writeHeader(200, {
                'Contenttype': 'application/json'
            });
            res.write(JSON.stringify(data));
        }
        res.end();
    });
    break;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM