一、路径
- 是全局变量 是一个字符串
- __dirname 代表当前js文件所在的目录的路径:绝对路径 文件夹(directory)
- __filename 代表当前js文件的路径:绝对路径 (不常用)
示例:
二、静态网站托管
基于上篇文章中发送网页到前端的优化:
由于req.url与文件路径相似 __dirname代表当前js文件所在的目录的路径
所以__dirname + req.ur l就是文件的路径
所以不需重复写加载单个资源的代码 而是利用托管自动加载所有资源:起到优化的作用
效果与之前完全一致 :
三、fs模块
1、读取文件
- fs.readFile(path,(err,data)=>{})
- path 填路径 可以绝对可以相对
- err代表读取失败
- data代表读取成功 它是一个buffer类型的数据(二进制数据流) 可以通过toString()转化为字符串
- 注意:res.end()方法接收字符串或者buffer
示例:
var fs = require("fs")
fs.readFile(__dirname + "/img/rose1.jpg", (err, data) => {
console.log(1, data)
})
fs.readFile(__dirname + "/test.txt", (err, data) => {
console.log(2, data)
})
fs.readFile(__dirname + "/qunar.html", (err, data) => {
console.log(3, data)
})
运行结果:
2、写入文件(创建文件)
- fs.writeFile(path ,data,callback(ere))
- 若文件存在,该方法写入的内容会覆盖原文件内容;若不存在就创建一个新的文件
- 若文件夹不存在会报错
- path 文件路径
- data 要写入文件的数据,可以是 String(字符串)
- callback 回调函数 只包含错误信息参数(err),在写入失败时返回
示例:文件存在时
fs.writeFile(__dirname + "/test.txt", "hello", function (err) {
console.log(err)
})
运行结果:
示例:文件不存在时
fs.writeFile(__dirname + "/test1.txt", "world", function (err) {
console.log(err)
})
运行结果:
3、删除文件
- fs.unlink(path,callback(err))
- path 文件路径
- callback(err) 删除的回调函数 err错误信息
示例:
fs.unlink(__dirname + "/test1.txt", (err) => {
console.log(err)
})
运行结果:
4、以追加方式写文件
- fs.appendFile(path, data, callback (err)
- path 文件路径
- data 追加的要写入文件的数据,可以是 String(字符串)
- callback(err) 回调函数 只包含错误信息参数(err),在写入失败时返回
示例:
fs.appendFile(__dirname + "/test.txt", " world", (err) => {
console.log(err)
})
运行结果:
5、创建目录
- fs.mkdir(path,callback(err))
- path 文件路径
- callback(err) 回调函数 创建失败时返回
示例:
fs.mkdir(__dirname + "/wenjianjia", (err) => {
console.log(err)
})
运行结果:
6、移动/重命名文件或目录
- 整个功能相当于重命名一个文件/文件夹路径
- fs.rename(oldPath, newPath, callback)
- oldPath 原目录/文件的完整路径及名
- newPath 新目录/文件的完整路径及名
- 若新路径与原路径相同而文件名不同,则为重命名
- callback(err) 操作完成回调函数;err操作失败对象
注:新路径和旧路径必须是同一个根盘
示例:
//移动
var oldpath = __dirname + "/test.txt"
var newpath = __dirname + "/wenjianjia/test.txt"
fs.rename(oldpath, newpath, (err) => {
console.log(err)
})
//重命名
var oldpath = __dirname + "/test1.txt"
var newpath = __dirname + "/retest1.txt"
fs.rename(oldpath, newpath, (err) => {
console.log(err)
})
运行结果:
7、拷贝文件
- fs.copy(oldPath, newPath, callback)
- oldPath 原文件的完整路径
- newPath 新文件的完整路径
- callback(err) 操作完成回调函数;err操作失败对象
- 拷贝文件以后两个文件都会存在磁盘中
示例:
var oldpath = __dirname + "/wenjianjia/test.txt"
var newpath = __dirname + "/test.txt"
fs.copyFile(oldpath, newpath, (err) => {
// fs.unlink(oldpath,(err)=>{}) 拷贝后删除原文件
console.log(err)
})
运行结果:
8、读取目录
- fs.readdir(path,(err,arr)=>{})
- path 填路径 可以绝对可以相对
- err 代表读取失败
- data 代表读取成功 返回一个装文件的数组
示例:
fs.readdir(__dirname, (err, arr) => {
console.log(arr)
})
运行结果:
四、网址url
组成:协议://ip:port/pathname?querystring#hash
eg:https://www.baidu.com/index.html?count=20&user=haha#top
五、url模块
- 功能:解析网址 可以把url网址解析为一个对象
- var urlobj=url.parse(req.url)
- urlobj.pathname urlobj.query
示例:
var url=require("url")
var str="https://blog.csdn.net/qq_56668869/article/details/126022225?spm=1001.2014.3001.5502"
var obj=url.parse(str)
console.log(obj)
运行结果:
示例(静态网站托管):
var http = require("http")
var fs = require("fs")
var url = require("url")
var app = http.createServer((req, res) => {
//req.url :代表前端请求的网址
console.log(req.url) //打印端口号后面的所有
var path = url.parse(req.url).pathname
fs.readFile(__dirname + "/scr" + path, (err, data) => {
//将src文件夹中的资源全部托管起来了 直接到src文件夹下面找文件
if (err) {
res.end("not found")
} else {
res.end(data)
}
})
})
app.listen(8088)
六、querystring模块
功能:可以把querystring参数解析为一个对象
var urlobj=url.parse(req.url)
var queryobj=querystring.parse(urlobj.query)
示例:
var querystring=require("querystring")
var obj=querystring.parse("username=haha&count=21&id=666666")
console.log(obj)
运行结果:
示例(静态网站托管):
var http = require("http")
var fs = require("fs")
var url = require("url")
var querystring = require("querystring")
var app = http.createServer((req, res) => {
var urlobj = url.parse(req.url)
var pathname = urlobj.pathname
if (pathname == "/") {
pathname = "/index.html"
} //指向首页文件
var path = __dirname + "/src" + pathname
//将src文件夹中的文件托管
fs.readFile(path, (err, data) => {
if (!err) {
res.setHeader("content-Type", "text/html")
res.end(data)
} else if (pathname == "/login") { //直接返回数据 不返回文件
var queryobj = querystring.parse(urlobj.query) //将网址中?后面的字符串 解析成对象
console.log(queryobj) //方便取出用户的账号密码或其他信息来进行后续数据处理
res.end("数据")
} else {
res.end("404 not found")
}
})
})
app.listen(8088)
七、mime模块
- mime.getType(pathOrExtension):获取给定路径或扩展的mime类型
- mime.getExtension(type):获得给定mime类型的扩展名 可以给网站请求的资源(html、css等)添加一个content-type
- 返回值都是字符串 没有后缀的文件也有mime类型 在未检测到或识别的情况下返回null
示例:
var mime=require("mime")
var re=mime.getType("a.js")
console.log(re)
var re1=mime.getExtension("text/css")
console.log(re1)
运行结果:
示例(静态网站托管):
var mime=require("mime")
var url=require("url")
var querystring=require("querystring")
var http=require("http")
var fs=require("fs")
var app=http.createServer((req,res)=>{
var urlobj=url.parse(req.url)
var pathname=urlobj.pathname
if(pathname=="/"){pathname="/index.html"}
var path=__dirname+"/src"+pathname
//console.log(path)
fs.readFile(path,(err,data)=>{
if(!err){
var type1=mime.getType(path) //将path转化为"text/css"这样的字符串
res.setHeader("content-Type",type1) //动态读取相应的文件类型 "text/html"、"text/css"、"image/jpg"等
res.end(data)
}
else if(pathname=="/login"){ //直接返回数据 不返回文件
let queryobj=querystring.parse(urlobj.query) //网址中?后面的字符串 解析成对象
console.log(queryobj) //方便取出用户的账号密码或其他数据
//把前端传过来的数据 去处理
res.end("登录成功")
}
else if(pathname=="/regist"){
res.end("注册")
}
else {
res.end("404 not found")
}
})
})
app.listen(8088)
八、各种路径
- 本地相对路径:
页面是本地打开的 在这个页面中写路径:file://x1/x2/x2/index.html
"./src/rose.jpg" 写这个路径的文件的页面是在本地打开的==> file://x1/x2/x2/src/rose.jpg
"src/rose.jpg" 写这个路径的文件的页面是在本地打开的 ==> file://x1/x2/x2/src/rose.jpg
- 本地绝对路径:
从根盘开始写路径:
eg: G:\h5\H5+CSS\code\nodejs
- 相对网络路径:
当前页面的网址 协议://ip:port/src/index.html ?querystring#hash
页面内的路径:./img/a.jpg==>协议://ip:port/src/img/a.jpg
- 绝对网络路径:
eg: "协议://ip:port /src/news/src/rose.jpg"
易错思考:
用户输入网址: http://192.168.6.172:8080/user/20220728/newspage
打开了一个页面,在这个页面中有一个img的src是 : "192.168.6.172:8080/src/rose.jpg"
请问192.168.6.172:8080这个服务器会受到req.url是什么?
答: "/user/20220728/192.168.6.172:8080/src/rose.jpg"
它真正的网址:"http://192.168.6.172:8080/user/20220728/192.168.6.172:8080/src/rose.jpg"
- 本地相对根路径:
例:用户本地打开: "file:///c:/xx/xx2/index.html"
页面中有一个img的src是 : "/src/rose.jpg"
它真正的路径:"file:///c:/src/rose.jpg"
- 网络相对根路径:
eg:"/src/rose.jpg"
思考:
用户输入网址: http://192.168.6.172:8080/user/20220728/newspage
打开了一个页面,在这个页面中有一个img的src是 : "/src/rose.jpg"
请问192.168.6.172:8080这个服务器会受到req.url是什么?
答:"/src/rose.jpg"
它真正的网址:"http://192.168.6.172:8080/src/rose.jpg"
九、网页的加载流程
1.用户浏览器的地址栏输入网址 回车 会请求一次服务
- 服务器(后端)会返回一个数据包 就是网页代码(html格式的文本文档)然后断开连接
2.浏览器开始运行解析html文本(此时还没有外部图片、css、js、字体库等资源)
- 解析时 遇到img的src属性 会异步地再次请求网络服务器,服务器返回数据包(image编码)然后断开连接 浏览器把图片的编码按照CSS结构进行渲染
- 解析时 遇到link的href属性 会异步地再次请求网络服务器,服务器返回数据包(对应编码) 然后加载出来
- 解析时 遇到xx的url属性 会异步地再次请求网络服务器,服务器返回数据包(对应编码) 然后加载
- 解析时 遇到script的src属性 会异步地再次请求网络服务器,服务器返回数据包(js编码) 然后用js引擎去执行编码
......
3.所有资源加载完毕开始页面渲染
- 页面按照解析好的DOM模型和CSS层叠样式表结合为renderTree然后绘制页面