文章目录
一、什么是node.js
1.回顾与思考
js代码能够浏览器解析是因为每个浏览器都有各自的js解析引擎:
js运行再浏览器环境就是前端,运行再node.js环境就可以作为后端:
2.node.js简介
二、fs文件系统模块
0.fs模块介绍
1.读取文件内容readFile()
2.使用readFile方法读取文件案例
代码:
// 第一步:导入fs模块 使用require 、 参数是模块的名字 一般导入什么模块名字,就用什么名字来接收
const fs = require("fs");
//第二步:调用fs.readFile()读取文件
// 参数一:想要读取的文件所在路径
// 参数二:读取文件时候采用的读取方式 一般默认指定为 utf8
// 参数三:回调函数 拿到读取成功和失败的结果 err dataStr
fs.readFile("../files/1.txt", "utf8", function (err, dataStr) {
// 打印失败的结果
//如果文件读取成功 则err的默认值为null dataStr是我们读取文件中的内容
console.log("err message:" + err);
console.log("-------------------");
// 打印成功的结果
console.log("dataStr message:" + dataStr);
});
结果如图所示:
如果使用该方法读取文件失败:
返回的值 err:错误对象 ;dataStr : undefined
3.判断文件是否读取成功
代码:
// 第一步 导入fs模块
var fs = require("fs");
//第二步 使用readFile方法读取文件
fs.readFile("../files/1.txt", "utf8", function (err, result) {
// 如果文件读取失败 err是对象-真 如果文件读取成功 err是null-假
if (err) {
//文件读取失败 打印读取文件失败的原因
return console.log("读取文件失败-原因是:" + err.message);
} else {
console.log("读取文件成功-结果是:" + result);
}
});
运行结果:
修改文件名字后,则读取文件失败,如图:
4.向指定文件写入内容
无论写入成功或者失败都会调用回调函数
代码:
//导入fs模块
var fs = require("fs");
//定义想写入文件的内容 待会以参数的形式传递给写入文件的函数中
var str = "我通过writeFile方法向1.txt文件中写入了内容";
//调用写入文件函数 writeFile()
// 三个必须有的参数 参数1:文件地址字符串
// 参数2:要写入文件的内容
// 可选参数:编码格式 不写默认utf8
// 参数3:回调函数
fs.writeFile("../files/1.txt", str, "utf-8", function (err) {
// 如果文件写入成功 err的值是null
// 如果写入失败 err是错误对象
console.log(err);
});
运行结果:
5.判断文件是否写入成功
代码:
var fs = require("fs");
fs.writeFile("../files/2.txt", "判断文件是否写入成功", function (err) {
// 如果文件写入成功 err是null假 如果写入失败 err是错误对象镇
if (err) {
console.log("文件写入失败,原因:" + err.message);
} else {
console.log("文件写入成功!");
}
});
运行结果:
注意:我在files/文件夹下没有2.txt 写入的时候会自动帮我生成2.txt
修改文件目录,导致文件写入失败,效果如图:
6.案例:实现成绩整理
代码:
// 导入fs模块
let fs = require("fs");
//读取文件
fs.readFile("../files/成绩.txt", "utf-8", function (err, res) {
//判断文件是否读取成功
if (err) {
return console.log("文件读取失败,原因" + err.message);
} else {
// console.log("文件读取成功:");
// console.log(res);
// 文件读取成功后 对其内容进行处理
// 1.将内容字符串按空格进行分割 并存入数组
const arrold = res.split(" ");
console.log(arrold);
console.log("-------------------");
// 2.对数组循环处理 没循环一次将等号变为冒号
const arrnew = [];
arrold.forEach((item) => {
arrnew.push(item.replace("=", ":"));
});
console.log(arrnew);
console.log("-------------------");
// 3.将处理后的数组进行拼接成为字符串
// 回车换行: /r/n
const newStr = arrnew.join("\r\n");
console.log(newStr);
console.log("-------------------");
// 4.写入文件
fs.writeFile("../files/成绩整理版本.txt", newStr, function (err) {
if (err) {
return console.log("文件写入失败:" + err.message);
} else {
console.log("文件写入成功!");
}
});
}
});
运行结果:
ti
7. 路径动态拼接问题
错误示例:
出现路径动态拼接错误的原因即解决方法:
使用完整路径代替相对路径:
完整路径:从盘符开始的
缺点:移植性差 不利于维护
如何同时解决上述问题:移植性差和动态拼接问题?
如下:利用__dirname
__dirname 打印绝对路径
完美解决示例:
因为__dirname:打印的是绝对路径 所以可以在上一层文件目录下 通过node 进入到相应目录执行文件
8、path路径模块
使用哪个模块之前都要通过require导入该模块
//注意:一个../会抵消它前面的一个路径
var Pathres1 = path.join("/a", "/b/c", "../", "./d", "file");
console.log(Pathres1);
9、时钟案例
正则表达式的exec方法:regStyle.exec():在本案例中传递的字符串是index.html文件字符串 ;之前regStyle定义的正则表达式匹配的是style标签 ,所以regStyle.exec()匹配成功则是数组,数组第0个元素则是与正则表达式相匹配的文本, 匹配失败则是null ;我们还需要用一个变量去接收这个结果 然后将结果中的style字符替换成空字符 因为在.css文件中不需要style标签;把替换后的新字符串再用newCss变量接收,然后将newCss字符串写入到index.css文件中
JS操作同css
完整源码:
// 导入fs 和 path两个模块
const fs = require("fs");
const path = require("path");
//定义正则表达式 分别匹配style和script标签
{
/* <style></style> */
}
// \s匹配空白字符; \S匹配非空白字符 两个一起组合就是匹配所有字符
const regStyle = /<style>[\s\S]*<\/style>/;
const regScript = /<script>[\s\S]*<\/script>/;
//调用fs模块读取文件
fs.readFile(
//当前是在code目录下 index.html是要读取的文件在和code文件夹同一层的素材文件夹中 所以需要../
path.join(__dirname, "../素材/index.html"),
"utf8",
function (err, dataStr) {
if (err) {
return console.log("文件读取失败:", +err.message);
} else {
// 读取文件成功: 调用对应的三个方法 分别拆解出css js html文件
resolveCss(dataStr);
resolveJs(dataStr);
resolveHTML(dataStr);
}
}
);
//定义 处理css样式的方法
function resolveCss(htmlStr) {
// 使用正则表达式提取需要的内容 返回结果 : 成功是数组 失败是null
const r1 = regStyle.exec(htmlStr);
// console.log(r1);
// 将内容中的style标签用空串替换
const newCss = r1[0].replace("<style>", "").replace("</style>", "");
// console.log(newCss);
// //调用fs的文件写入方法 将newCss向clock文件夹下写入到index.css文件中
fs.writeFile(
path.join(__dirname + "/clock/index.css"),
newCss,
function (err) {
if (err) {
return console.log("写入失败" + err.message);
} else {
console.log("css文件写入成功");
}
}
);
}
// 定义处理JS样式的方法
function resolveJs(htmlStr) {
const r2 = regScript.exec(htmlStr);
const newJs = r2[0].replace("<script>", "").replace("</script>", "");
fs.writeFile(path.join(__dirname + "/clock/index.js"), newJs, function (err) {
if (err) {
return console.log("JS文件写入失败" + err.message);
} else {
return console.log("JS文件写入成功");
}
});
}
//处理html
function resolveHTML(htmlStr) {
const newHTML = htmlStr
.replace(regStyle, '<link rel="stylesheet" href="./index.css" />')
.replace(regScript, '<script src="./index.js"></script>');
//将newHTML内容写入clock文件夹下
fs.writeFile(
path.join(__dirname, "./clock/index.html", newHTML, function (err) {
if (err) {
return console.log("html文件写入失败" + err.message);
} else {
return console.log("html文件写入成功");
}
})
);
}
// 5.1 定义处理 HTML 结构的方法
function resolveHTML(htmlStr) {
// 5.2 将字符串调用 replace 方法,把内嵌的 style 和 script 标签,替换为外联的 link 和 script 标签
const newHTML = htmlStr
.replace(regStyle, '<link rel="stylesheet" href="./index.css" />')
.replace(regScript, '<script src="/index.js"></script>');
// 5.3 写入 index.html 这个文件
fs.writeFile(
path.join(__dirname, "./clock/index.html"),
newHTML,
function (err) {
if (err) return console.log("写入 HTML 文件失败!" + err.message);
console.log("写入 HTML 页面成功!");
}
);
}
10 http模块
11.服务器
示例:
代码:
//导入http模块
const http = require("http");
// 利用模块创建服务器示例
const serve = http.createServer();
//为服务器serve绑定request事件 监听客户端的请求
serve.on("request", function (req, res) {
console.log("someone visit our serve");
});
//启动服务器;两个参数 第一个 端口号; 第二个 回调函数;
serve.listen(8080, function () {
//如果服务器启动成功则打印如下
console.log("serve running at http://127.0.0.1:8080");
});
//当我们在浏览器访问(请求) http://127.0.0.1:8080 服务器的地址 则会出发request事件 打印 :someone visit our serve
req请求对象示例:
res请求对象的示例:
代码如下:
const http = require("http");
const serve = http.createServer();
serve.on("request", (req, res) => {
const str = `你发起请求的url是${req.url},请求方式是${req.method}`;
//防止中文乱码 设置响应头部
res.setHeader("Content-Type", "text/html;charset=utf-8");
console.log(str);
res.end(str);
});
// 开启服务器
serve.listen(80,()=>{
console.log('serve running at http://127.0.0.1');
})
12.根据不同url响应不同的html内容
动态响应内容示例代码:
const http = require("http");
const serve = http.createServer();
// 服务器绑定请求事件
serve.on("request", function (req, res) {
//1.获取发起请求的url地址
const url = req.url;
//2.设置默认响应的内容是 404 Not found
let Content = "<h1>404 Not found</h1>";
//3.判断用户发起的请求 是否为 / 或者 /index.html 或者/about.html 如果匹配到其中之一则显示对应的内容
if (url === "/" || url === "/index.html") {
Content = "<h1>首页</h1>";
} else if (url === "/about.html") {
Content = "<h1>关于页面</h1>";
}
//4.设置响应头部Content-Type 防止中文乱码
res.setHeader("Content-Type", "text/html; charset=utf-8");
//5.使用res.send方法将内容响应到客户端
res.end(Content);
});
serve.listen(80, () => {
//监听服务器 只要服务器一启动就会调用回调函数
console.log("server running at http://127.0.0.1");
});
//总结:要实现输入不同的url,显示对应内容,显示内容是通过res.end()方法将内容写入到发起请求的页面中
// 1.当我们通过http模块创建服务器的时候,给服务器绑定request请求事件。
// request请求事件:监听客户端发送的请求
// 当有人对我们创建的服务器发起了请求 ,则request会监听到,然后执行回调函数,
// 回调函数有两个参数 第一个是req客户端对象 第二个res是服务器对象
// 2.我们通过req.url可以获取到客户端发起请求所在的url地址
// 3.我们对获取到的url地址通过if匹配 从而实现内容匹配
// 4.为了防止中文乱码 我们在res.end()发送内容时需要设置响应头部
案例 :实现时钟的web服务器
步骤5-优化资源的请求路径实现的功能是:
在未优化路径之前:我们访问首页是通过地址 :http://127.0.0.1/clock/index.html
优化之后可以实现,通过地址:http://127.0.0.1/index.html 访问首页 或者 通过地址:127.0.0.1/ 访问首页
完整源代码:
//1. 导入需要的三个模块 http:创建服务器相关-path:处理路径-fs:文件操作相关
const http = require("http");
const path = require("path");
const fs = require("fs");
//2.服务器操作
// 创建服务器--监听服务器的request事件-启动服务器
const server = http.createServer();
server.on("request", function (req, res) {
//3.1获取客户端请求的url地址
// 如果我们请求的是clock文件夹下的index.html文件 则url显示:/clock/index.html
// 可以看出我们获得到的url不是完整的文件路径 index.html完整的路径应该是:D:\A-personal-web-workspace\Node.js_record\day02\code + \clock\index.html
//实际上就是 : __dirname + url
const url = req.url;
//3.2 把请求url地址,映射为具体完整的文件的存储路径
// __dirnamrd打印: D:\A-personal-web-workspace\Node.js_record\day02\code
// const fpath = path.join(__dirname, url);
// 优化路径之后:
//5.1预定义一个空白的文件存放路径
let fpath = "";
if (url === "/") {
// 当我们访问跟路径时 ,我们直接修改fpath为拼接号的首页地址
fpath = path.join(__dirname, "./clock/index.html");
} else {
//用户请求的不是根路径
// 注意 此时的url要从: /clock/index.html 统一 转换为:/index.html ;即省略:/clock 我们手动字符串拼接即可
fpath = path.join(__dirname, "/clock" + url);
}
//4.1根据之前映射过来的完整文件路径 通过fs模块读取文件的内容
fs.readFile(fpath, "utf-8", (err, dataStr) => {
if (err) {
//如果文件读取失败 则向客户端响应固定的错误消息
return res.end("404 Not found!");
} else {
//文件读取成功,则将读取成功的文件的内容发送到客户端
res.end(dataStr);
}
});
});
server.listen(80, () => {
console.log("server running at http://127.0.0.1");
});