如何使用Node.js搭建简单的静态文件服务器
沉沙 2018-07-19 来源 : 阅读 618 评论 0

摘要:本篇Node.js教程探讨了如何使用Node.js搭建简单的静态文件服务器,希望阅读本篇文章以后大家有所收获,帮助大家对Node.js的理解更加深入。

做前端有时会采用一些复杂框架,在文件系统中直接打开页面(用file:///方式打开),往往会报跨域的错,类似于“XMLHttpRequest cannot load ...(文件名). Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.”。这时,我们可以快速搭建一个简单的静态文件服务器,用Node.js最合适。

看过龍太的文章后(地址://www.jianshu.com/p/76c1a9f39a36),我觉得这篇文章里的服务器实现还是“麻雀虽小,五脏俱全”的。不过代码有Bug,比如当用户请求一个目录时,代码虽然可以自动搜索目录里的index.html,但在显示过程中出现异常。经过研究和修改,我把原文章中的3个js脚本合为一个,并解决了这个问题。而且优化了体验,比如当运行这个js文件时,载入项目主页的浏览器会自动弹出来。

 

1.在前端项目根目录下创建server.js,代码如下:

 

  1 "use strict";  2 //加载所需要的模块  3 var http = require('http');  4 var url = require('url');  5 var fs = require('fs');  6 var path = require('path');  7 var cp = require('child_process');  8   9 //创建服务 10 var httpServer = http.createServer(processRequest); 11  12 var port = 8080; 13  14 //指定一个监听的接口 15 httpServer.listen(port, function() { 16     console.log(`app is running at port:${port}`); 17     console.log(`url: //localhost:${port}`); 18     cp.exec(`explorer //localhost:${port}`, function () { 19     }); 20 }); 21  22 //响应请求的函数 23 function processRequest (request, response) { 24     //mime类型 25     var mime = { 26         "css": "text/css", 27         "gif": "image/gif", 28         "html": "text/html", 29         "ico": "image/x-icon", 30         "jpeg": "image/jpeg", 31         "jpg": "image/jpeg", 32         "js": "text/javascript", 33         "json": "application/json", 34         "pdf": "application/pdf", 35         "png": "image/png", 36         "svg": "image/svg+xml", 37         "swf": "application/x-shockwave-flash", 38         "tiff": "image/tiff", 39         "txt": "text/plain", 40         "wav": "audio/x-wav", 41         "wma": "audio/x-ms-wma", 42         "wmv": "video/x-ms-wmv", 43         "xml": "text/xml" 44     }; 45      46     //request里面切出标识符字符串 47     var requestUrl = request.url; 48     //url模块的parse方法 接受一个字符串,返回一个url对象,切出来路径 49     var pathName = url.parse(requestUrl).pathname; 50  51     //对路径解码,防止中文乱码 52     var pathName = decodeURI(pathName); 53  54     //解决301重定向问题,如果pathname没以/结尾,并且没有扩展名 55     if (!pathName.endsWith('/') && path.extname(pathName) === '') { 56         pathName += '/'; 57         var redirect = "//" + request.headers.host + pathName; 58         response.writeHead(301, { 59             location: redirect 60         }); 61         //response.end方法用来回应完成后关闭本次对话,也可以写入HTTP回应的具体内容。 62         response.end(); 63     } 64  65     //获取资源文件的绝对路径 66     var filePath = path.resolve(__dirname + pathName); 67     console.log(filePath); 68     //获取对应文件的文档类型 69     //我们通过path.extname来获取文件的后缀名。由于extname返回值包含”.”,所以通过slice方法来剔除掉”.”, 70     //对于没有后缀名的文件,我们一律认为是unknown。 71     var ext = path.extname(pathName); 72     ext = ext ? ext.slice(1) : 'unknown'; 73  74     //未知的类型一律用"text/plain"类型 75     var contentType = mime[ext] || "text/plain"; 76  77     fs.stat(filePath, (err, stats) => { 78         if (err) { 79             response.writeHead(404, { "content-type": "text/html" }); 80             response.end("<h1>404 Not Found</h1>"); 81         } 82         //没出错 并且文件存在 83         if (!err && stats.isFile()) { 84             readFile(filePath, contentType); 85         } 86         //如果路径是目录 87         if (!err && stats.isDirectory()) { 88             var html = "<head><meta charset = 'utf-8'/></head><body><ul>"; 89             //读取该路径下文件 90             fs.readdir(filePath, (err, files) => { 91                 if (err) { 92                     console.log("读取路径失败!"); 93                 } else { 94                     //做成一个链接表,方便用户访问 95                     var flag = false; 96                     for (var file of files) { 97                         //如果在目录下找到index.html,直接读取这个文件 98                         if (file === "index.html") { 99                             readFile(filePath + (filePath[filePath.length-1]=='/' ? '' : '/') + 'index.html', "text/html");100                             flag = true;101                             break;102                         };103                         html += `<li><a href='${file}'>${file}</a></li>`;104                     }105                     if(!flag) {106                         html += '</ul></body>';107                         response.writeHead(200, { "content-type": "text/html" });108                         response.end(html);109                     }110                 }111             });112         }113 114         //读取文件的函数115         function readFile(filePath, contentType){116             response.writeHead(200, { "content-type": contentType });117             //建立流对象,读文件118             var stream = fs.createReadStream(filePath);119             //错误处理120             stream.on('error', function() {121                 response.writeHead(500, { "content-type": contentType });122                 response.end("<h1>500 Server Error</h1>");123             });124             //读取文件125             stream.pipe(response);126         }127     });128 }

 

 2.在前端项目根目录下打开命令提示符或终端,输入以下命令就可以启动小服务器啦。

node server.js

 

本文由职坐标整理并发布,了解更多内容,请关注职坐标WEB前端Node.js频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程