一、fs模块
fs模块最重要的一个功能就是异步读取文件(readFile),第一个参数文件,第二个参数是回调函数。
fs.readFile('文件名', (err, data) => {
if (err) throw err;
console.log(data);
});
我们现在要结合这个方法进行一个页面的读取内容。
var http = require("http");
var fs = require("fs");
// 创建服务器
var server = http.createServer(function(req,res){
fs.readFile("./public/zhoujielun.html",function(err,data) {
res.end(data)
})
})
// 监听
server.listen(3000)

二、路由(※)
上面的案例,我无论输入什么URL都会显示zhoujielun.html这个页面。
var server = http.createServer(function(req,res){
fs.readFile("./public/zhoujielun.html",function(err,data) {
res.end(data)
})
})

上面的路由地址是随便写的,你会发现无论路由什么样,都会显示该页面,此时我们就可以利用这个特性完成我们的路由设计。
我们可以通过req.url()得到用户输入的URL地址。
var server = http.createServer(function(req,res){
// 设置字符集
res.setHeader("Content-Type","text/html;charset=UTF8");
if(req.url === "/star/zhoujielun") {
fs.readFile("./public/zhoujielun.html",function(err,data) {
res.end(data)
})
} else if(req.url === "/star/wanglihong"){
fs.readFile("./public/wanglihong.html",function(err,data) {
res.end(data)
})
} else {
res.end("无页面显示")
}
})
比如我们访问/star/zhoujielun
再比如我们要访问/star/wanglihong
我们之前的认知是路由即文件夹,但是我们Node.js颠覆了我们的认知,通过路由进行页面的读取,这个就是顶层路由设计。
顶层路由设计:
△:物理文件层级的URL是没有任何关系的;
△:Node.js是可以做顶层路由设计的!一个页面的URL是可以自定义的;
△:用户输入的URL是可以映射任何HTML页面的;
现在有很多大型网站都是这种顶层路由设计,比如知乎。
https://www.zhihu.com/people/guozi-51-501/answer 用户的回答
https://www.zhihu.com/people/guozi-51-501/zvideos 用户的提问
https://www.zhihu.com/people/guozi-51-501/asks 用户的提问
https://www.zhihu.com/people/guozi-51-501/posts 用户的文章
https://www.zhihu.com/people/guozi-51-501/columns 用户的专栏
老一代的路由实际上都是映射服务器的物理文件夹目录。比如https://weibo.com/p/1005052970323452/photos?from=page_100505&mod=TAB#place。
三、模仿知乎路由的顶层设计。
var server = http.createServer(function(req,res){
// 设置字符集
res.setHeader("Content-Type","text/html;charset=UTF8");
// 得到用户的url
var url = req.url;
// 使用正则表达式进行信息的获取
var arr = url.match(/\/user\/(.+)\/(.+)$/);
console.log(arr)
// 如果没有对应的路由地址,抛出错误
if(!arr) {
res.end("<h1>无页面显示</h1>")
return;
}
// 获取信息
// 正则的第一项
var $1 = arr[1];
// 正则的第二项
var $2 = arr[2]
// 数据模拟
var user = {
"zhoujielun":"周杰伦",
"zhangyi":"张译",
"wujing":"吴京",
"yiyangqianxi":"易烊千玺",
};
var list = {
"post":"文章",
"ask":"提问",
"answer":"回答",
"pins":"想法",
}
// 页面返回的内容
res.write("<h1>"+user[$1]+"你好</h1>")
res.end("<h2>欢迎来到"+list[$2]+"版块</h2>")
})
我们就模拟了知乎的路由设计。
四、顶层路由设计会遇到的问题。
我们请求zhoujielun.html文件为例,路由地址是/star/zhoujielun
页面的内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>你好,我是周杰伦</h1>
<img src="images/zhoujinlun.jpg" alt="">
</body>
</html>

通过上图你会发现页面中只有文字的展示,没有图片的展示,但是HTML结构中是有img标签的,为什么不能加载?
答:该图片的URL路径是没有物理文件夹的。
现在这张图片的真实物理地址是:http://127.0.0.1:3000/star/images/zhoujielun.html,但是图片物理存放地址是在:C:\node_study\public\images,所以一定不能按需加载。
那么解决办法就是对每一张图片进行请求设置。
var server = http.createServer(function(req,res){
console.log(req.url)
// 设置字符集
res.setHeader("Content-Type","text/html;charset=UTF8");
//对页面的内容进行请求
if(req.url === "/star/zhoujielun") {
fs.readFile("./public/zhoujielun.html",function(err,data) {
res.end(data)
})
//对页面的图片地址进行请求
} else if(req.url=="/star/images/zhoujinlun.jpg"){
res.setHeader("Content-Type","image/jpg");
// 读取图片
fs.readFile("./public/images/zhoujinlun.jpg",function(err,data){
res.end(data)
})
}else{
res.end("无页面显示")
}
})

问题来了,如果图片的数量很多怎么办?每一张都势必要进行对路由的请求和渲染,也就是要给每一张图片开辟路由地址,不仅仅是图片,其他文件也是一样的。
解决办法就是我们后面要学习的express的中间件来静态化一个文件夹。目的就是当前这个文件夹内部的文件自动就有了URL路由,不用每个都单独设置。
需要注意的是:使用Node.js进行请求文件或资源的时候,需要设置对应的Content-Type,就是文件的请求类型。
常见的类型有:
text/html:HTML格式
text/css:CSS格式
text/plain:纯文本格式
text/xml:XML格式
image/gif:GIF文件格式
iamge/jpeg:JPEG图片格式
image/png:PNG图片格式
res.setHeader("Content-Type","text/html;charset=UTF8") //HTML
res.setHeader("Content-Type"," text/css ") //CSS
res.setHeader("Content-Type"," image/png ") //png格式的图片
