Node.js 官方文档
一、fs 介绍
fs模块最重要的一个功能就是异步读取文件(readFile),第一个参数文件,第二个参数是回调函数
fs 读取页面内容
var http = require("http");
var fs = require("fs");
// 创建服务器
var server = http.createServer(function (req,res) {
//设置字符集
res.setHeader("Content-type","text/html;charset=UTF8");
fs.readFile("./public/kobe.html",(err,data) => {
if(err) throw err;
res.end(data)
})
})
//监听
server.listen(3000)
二、路由☆☆☆☆☆
fs读取文件中 无论输入什么URL都会显示kobe.html这个页面
- 上图中的路由地址是随便写的,无论路由什么样,都会显示kobe.html这个页面
- 此时就可以利用这个特性完成我们的路由设计
- 可以通过req.url得到用户输入的URL的地址
2.1 顶层路由设计
var http = require("http");
var fs = require("fs");
// 创建服务器
var server = http.createServer(function (req,res) {
//获取路由
console.log(req.url);
//设置字符集
res.setHeader("Content-type","text/html;charset=UTF8");
if(req.url === "/star/kobe"){
fs.readFile("./public/kobe.html",(err,data) => {
if(err) throw err;
res.end(data)
})
}else if(req.url === "/star/james"){
fs.readFile("./public/james.html",(err,data) => {
if(err) throw err;
res.end(data)
})
}else{
res.end("<h1>没找到相关页面</h1>")
}
})
//监听
server.listen(3000)
之前的认知是路由即文件夹,但是NodeJS颠覆了我们的认知,通过路由进行页面的读取,这个就是顶层路由设计
顶层路由设计:
- 物理文件层次和URL是没有任何关系的
- NodeJS是可以做顶层路由设计的!一个页面URL是可以自定义的
- 用户的输入的URL是可以映射任何HTML页面的
现在有很多的大型网站都是这种顶层路由设计的,比如知乎网站
老一代的路由实际都是映射服务器的物理文件夹目录
2.2 小案例:模仿知乎路由的顶层设计
var http = require("http");
var server = http.createServer(function (req,res) {
//设置字符集
res.setHeader("Content-type","text/html;charset=UTF8")
// 得到用户的url
let urlStr = req.url;
// 使用正则表达式进行信息的获取
let arr = urlStr.match(/\/user\/(.+)\/(.+)$/);
// 如果没有对应的路由地址,抛出错误
if(!arr){
res.end ("<h1>没找到相关页面</h1>");
return;
}
console.log(arr)
//获取信息
//正则第一项
let $1 = arr[1];
//正则第2项
let $2 = arr[2];
//模拟数据
var user = {
"kobe":"科比布莱恩特",
"james":"勒布朗詹姆斯",
"al":"阿伦·艾弗森",
"kd":"凯文杜兰特",
}
var list = {
"post":"文章",
"ask":"提问",
"answer":"回答",
"pins":"想法",
}
//页面返回
res.write(`<h1>${user[$1]} 你好</h1>`);
res.end(`<h2>欢迎来到${list[$2]}板块</h2>`);
})
server.listen(3000)
2.3 顶层路由设计会遇到的问题
在kobe.html 页面中添加本地图片
请求地址
var http = require("http");
var fs = require('fs');
var server = http.createServer(function (req,res) {
res.setHeader("Content-type","text/html;charset=UTF8");
if(req.url == "/str/kobe"){
fs.readFile("./public/kobe.html",(err,data) => {
if(err){
throw err;
return
}
res.end(data)
})
}else{
res.end("<h1>没找到相关页面</h1>")
}
})
server.listen(3000)
页面中不会渲染出图片
通过上图你会发现页面中只有文字的展示,没有图片的展示,但是HTML结构中是有img标签的,为什么不能加载?
该图片的url路径是没有物理文件夹的
现在这张图片的真实物理地址是http://127.0.0.1:3000/str/images/kobe.jpg,但是图片物理存放地址是在C:\node-study\public\images,所以一定不能按需加载
解决办法就是对每一张图片进行请求
var http = require("http");
var fs = require('fs');
var server = http.createServer(function (req,res) {
res.setHeader("Content-type","text/html;charset=UTF8");
if(req.url == "/str/kobe"){
fs.readFile("./public/kobe.html",(err,data) => {
if(err){
throw err;
return
}
res.end(data)
})
}else if(req.url == "/str/images/kobe.jpg"){
res.setHeader("Content-type","image/jpg");
fs.readFile("./public/images/kobe.jpg",(err,data) =>{
res.end(data)
})
}else{
res.end("<h1>没找到相关页面</h1>")
}
})
server.listen(3000)
问题来了,如果图片的数量很多怎么办?每一张都势必要进行对路由的请求和渲染,也就是要给每一张图片都要开辟路由地址,不仅仅是图片,其他文件也是一样的
解决办法就是express的中间件来静态化一个文件夹。目的就是当前的这个文件夹内部的文件自动就有了URL路由,不用每一个都单独设置
2.4 ContentType 文件请求类型
常见的请求类型
text/html:HTML格式
text/css:CSS格式
text/plain:纯文本格式
text/xml:XML格式
image/gif:gif图片格式
image/jpeg:jpg图片格式
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格式的图片