Node搭建一个简单的静态服务器,具有一些基本功能.javascript
功能:css
Node重定向写法能够参考stackoverflow.com/questions/4…html
我在文件里面设置了/static为静态资源的文件目录,所以http://localhost:8080/其实就是默认打开的就是D:\xxx\staticjava
// server.js 这里其实应该对代码进行拆分下,稍微整洁点
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
var mime = require('./mime'); // 加载咱们的mime.js
var config = require('./config');
const port = 8080;
const server = http.createServer(function(req,res){
var pathName = url.parse(req.url).pathname; // 获取文件名"/xxx"
// 对中文进行解码,防止乱码
pathName = decodeURI(pathName);
// 重定向: 考虑定义标准的url,以'/'结尾.
if(path.extname(pathName) === ''){ // 没有扩展名
if(pathName.charAt(pathName.length-1) !== '/'){
pathName += '/';
var redirect = encodeURI('http://' + req.headers.host + pathName); // 记得encodeURI,否则中文目录报错
console.log(redirect);
res.writeHead(301,{
location: redirect
});
}
}
// 获取资源的绝对路径
var realFilePath = path.resolve(__dirname+'/static'+ pathName);
console.log(realFilePath);
// 获取对应文件的文档类型
var ext = path.extname(pathName); // 获取后缀名,如'.html'
ext = ext?ext.slice(1): 'notKnow'; // 取掉.符号
if (ext.match(config.Expires.fileMatch)) {
var expires = new Date();
expires.setTime(expires.getTime() + config.Expires.maxAge * 1000);
// 设置响应头
res.setHeader("Expires", expires.toUTCString());
res.setHeader("Cache-Control", "max-age=" + config.Expires.maxAge);
}
// 定义未知文档的类型MIME
var contentType = mime[ext] || "text/plain"; // 后缀名存在就进行映射,不存在就是'text/plain'
// 判断文件是否存在
fs.stat(realFilePath,function(err,stats){
// err
if(err){
// 也能够定制本身的404页面
res.writeHead(404,{'content-type': 'text/html'});
res.end('<h3>404 Not Found</h3>');
}
// 存在
if(stats.isFile()){
console.log('is file');
res.writeHead(200,{'content-type': contentType});
// 开始读取文件
var stream = fs.createReadStream(realFilePath);
// 读取时候错误处理
stream.on('error',function(){
res.writeHead(500,{'content-type': contentType});
});
// 返回文件内容
stream.pipe(res);
}
// 路径是目录的状况,列出当前目录下文件
if(stats.isDirectory() ){
var html = '<head><meta charset="utf-8"></head>';
// 读写该目录下的内容 files是文件数组
fs.readdir(realFilePath,function(err,files){
if(err){
console.log('目录文件读取失败');
}else{
console.log('is directory' + files); // test
for(var i = 0;i < files.length;i++){
//测当前目录下是否有index.html文件
// if (files[i] === "index.html") {
// res.writeHead(200, { "content-type": "text/html" });
// res.end();
// break;
// }
html += "<div><a href='"+files[i]+"'>"+files[i]+"</a></div>";
}
}
res.writeHead(200,{'content-type': 'text/html'});
res.end(html);
});
}
});
}).listen(port,function(){
console.log('Server running at port:' + port)
});复制代码
// config.js
exports.Expires = {
fileMatch: /^(gif|png|jpg|js|css)$/ig, // 这只是个demo
maxAge: 60 * 60 * 24 * 365
};复制代码
//mime.js 其实早就有这种模块的.
module.exports = {
"css": "text/css",
"gif": "image/gif",
"html": "text/html",
"ico": "image/x-icon",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"js": "text/javascript",
"json": "application/json",
"pdf": "application/pdf",
"png": "image/png",
"svg": "image/svg+xml",
"swf": "application/x-shockwave-flash",
"tiff": "image/tiff",
"txt": "text/plain",
"wav": "audio/x-wav",
"wma": "audio/x-ms-wma",
"wmv": "video/x-ms-wmv",
"xml": "text/xml"
};复制代码
参考资料:www.infoq.com/cn/news/201…json
if(stats.isFile()){
^
TypeError: Cannot read property 'isFile' of undefined复制代码