创建一个文件夹myweb,我们的程序能够自动为里面的文件,图片,css,js加上路由.实现一个小小的阿帕奇.
基本思想就是一句话:
用户输入什么url,我就真的用fs去读那个文件
代码如下:
var http=require("http");
var fs=require("fs");
var url=require("url");
var path=require("path");
var querystring=require("querystring");
//准备一个映射关系对
var mime={
".jpg":"image/jpeg",
".jpeg":"image/jpeg",
".gif":"image/gif",
".png":"image/png",
".html":"text/html;charset=UTF-8",
".css":"text/css",
".js":"application/x-javascript",
}
var server=http.createServer((req,res)=> {
//得到用户读取什么,比如用户输入http://127.0.0.0.1/myweb/1.png这个文件
var pathname=url.parse(req.url).pathname;
//得到拓展名
var extname=path.extname(pathname);
console.log("extname:"+extname);
//如果URL中不存在拓展名,此时就表示这是一个文件夹,此时自动补全/index.html即可.
if(!extname){
//如果不是以/结尾,此时就会造成浏览器识别图片路径层次有问题
//比如http:127.0.0.1:3000/b 和http:127.0.0.1:3000/b/不一样,同样的一张图片q.png
//前者认为是同级目录下的图片,后者认为是b文件夹中的
if(pathname.substr(-1)!="/"){
res.writeHead(302,{"Location":pathname+"/"});
}
pathname+="/index.html";
}
//真的读取这个文件,此时就要真的去读取myweb中的0.jpg文件
fs.readFile("./myweb/"+pathname,function(err,data){
if(err){
res.end("没有这个文件");
return;
}
//检查是否属于我已知的mime类型
if(mime.hasOwnProperty(extname)){
res.setHeader("content-type",mime[extname]);
}
res.end(data);
})
});
server.listen(3000);
注意:有几个不好的用的地方,首先是content-type的事
- 就是说如果我们访问的是.html文件,此时content-type就是text/html.如果是图片,此时应该是image/jpeg.请参考mine网站 添加链接描述
- 然后就是不能自动识别.index文件.比如我们输入http://127.0.0.1:3000/b 应该读取myweb里面的b文件夹里面的index.html
解决办法很新颖:这种路径都没有拓展名.如果用户输入了一个URL不存在的拓展名,则自动补充/index.html即可.
还有一个更大的问题,就是304的问题,304状态码是not modified.当文件没有改变的时候,服务器发出304状态码,拒绝传输文件.我们的小程序没有这样的识别,我们也解决不了,因为确实是太复杂,还要利用session和cookie保存镜像.