Node.js是一个基于chrom V8引擎的一个JavaScript的运行环境。它可以用来开发后端程序。
Node.js像浏览器一样,也内置有一些API,这些api中最主要的有 fs模块、path模块、http模块三大模块。
一、fs模块
1. fs.readfile() 读取指定文件中的内容
fs.readfile() 语法格式:
fs.readfile( path[, options], callback)
参数1:必选,字符串,表示文件的路径;
参数2:可选,表示以什么编码格式来读取文件,一般是utf8;
参数3:必选,文件读取完成后,通过回调函数拿到读取的结果。回调函数参数(err, dataStr)
代码示例:
// 1.导入fs模块
const fs = require('fs')
// 2.调用fs.readfile()方法读取文件
fs.readFile('./1.txt','utf8', function(err,dataStr){
// 2.1 打印失败的结果
// 如果读取成功,err为null
// 如果读取失败,err为 错误对象, dataStr的值为 undefined
console.log(err)
console.log('------')
// 2.2 打印成功的结果
console.log(dataStr)
})
2. fs.writeFile() 向指定文件写入内容
语法格式:
fs.readfile( path, data[, options], callback)
参数1:必选,字符串,表示文件的路径,如果该文件不存在,就会创建一个新文件;
参数2:必选,表示要写入的内容,此行为会覆盖文件之前的内容;
参数3:可选,表示以什么编码格式写入文件内容,一般是utf8;
参数4:必选,文件写入完成后的回调函数。
代码示例:
// 1.导入fs模块
const fs = require('fs');
// 2.调用 fs.writeFile() 方法
fs.writeFile('2.txt', 'abcd', function(err){
// 如果写入成功,err 值为 null
// 如果写入失败,err 值为 一个错误对象
console.log(err);
})
// 3.查看文件内容
fs.readFile('2.txt', 'utf8',function(err, dataStr){
console.log(err); // null
console.log(dataStr); // abcd
})
3. 小小案例
将‘小红=88 小明=90 狗蛋=75 二愣子=65 小王=98’,成绩整理成'小红:88', '小明:90', '狗蛋:75', '二愣子:65', '小王:98',并换行输出.
// 1.导入fs模块
const fs = require('fs');
// 2.读取文件内容
fs.readFile('3.txt', 'utf8', (err, dataStr)=>{
// 3.判断是否读取成功
if(err){
return console.log('读取文件失败' + err.message);
}
// console.log('读取文件成功' + dataStr); 小红=88 小明=90 狗蛋=75 二愣子=65 小王=98
// 4.处理数据
let newArr = [];
let arr = dataStr.split(' ');
for(let i=0;i<arr.length;i++){
newArr[i] = arr[i].replace('=',':');
}
let str = newArr.join('\r\n');
// 5.写入内容
fs.writeFile('4.txt', str, (err)=>{
if(err){
console.log('写入失败'+err.message);
}
console.log('写入成功');
})
})
3. fs模块-路径动态拼接问题
在使用fs模块操作文件时,如果提供的路径是以./ ../ 开头的相对路径,很容易出现路径动态拼接错误的问题。
原因:代码在运行的时候,会以执行node命令所处的目录,动态拼接出被操作文件的完整目录。
如上图,被操作文件的目录是当前node命令执行目录与js文件中路径拼接而成。
解决方法:将js文件中的路径改为绝对路径就可以了。
const fs = require('fs')、
// 换成绝对路径 注意转义
fs.readFile('C:\\Users\\legion\\Desktop\\file\\1.txt','utf8', function(err,dataStr){
console.log(dataStr)
})
上面方法虽然可以解决问题,但是代码可移植性差,难以维护。
node提供了一个 __dirname 表示当前文件所处路径
const fs = require('fs')、
// 换成绝对路径 注意转义
fs.readFile(__dirname + '/1.txt','utf8', function(err,dataStr){
console.log(dataStr)
})
可以使用__dirname 拼接被操作文件相对路径,解决这个问题。
二、path模块
1. path.join()方法
此方法可以将多个路径片段,拼接为完整的路径字符串。
const path = require('path');
// ../ 会抵消前面的一层路径
const pathStr = path.join('/a', '/b/c', '../', '/d', 'e');
console.log(pathStr); // \a\b\d\e
以后凡是涉及到路径拼接的问题,都要使用path.join()方法进行处理,尽量不要使用 + 进行字符串拼接。
2. path.basename()方法
此方法可以从一个文件路径中,获取到文件的名称。
这个方法可以有第二个参数,表示该文件的扩展名,加上之后,输出的就只有文件的名字。
const path = require('path');
const fpath = 'c:/a/b/c/index.html';
console.log(path.basename(fpath)); // index.html
// 这个方法可以有第二个参数,表示该文件的扩展名,加上之后,输出的就只有文件的名字
console.log(path.basename(fpath, '.html')); // index
3. path.extname()方法
此方法可以从一个文件路径中,获取到文件扩展名。
const path = require('path');
const fpath = 'c:/user/legion/a/b/index.html';
console.log(path.extname(fpath)); // .html
4. 综合案例
将一个html 文件中的 css,js,html 分离出来并分别放到新文件中。
const fs = require('fs');
const path = require('path');
// 1.定义正则表达式
const regStyle = /<style>[\s\S]*<\/style>/;
const regScript = /<script>[\s\S]*<\/script>/;
// 2.读取文件
fs.readFile(path.join(__dirname, '点名器.html'), 'utf8', (err, dataStr)=>{
if(err){
return console.log('文件读取失败');
}
// 3.拆解 css,js,html 文件
resolveCSS(dataStr);
resolveJS(dataStr);
resolveHTML(dataStr);
})
// 定义分解css 方法
function resolveCSS(htmlStr){
const r1 = regStyle.exec(htmlStr);
// 替换字符串中的一些内容
const newCSS = r1[0].replace('<style>', '').replace('</style>', '');
// 写入 CSS 文件中
fs.writeFile(path.join(__dirname, 'index.css'), newCSS, (err)=>{
if(err){
console.log('写入css失败');
}
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, 'index.js'), newJS, (err)=>{
if(err) console.log('写入js失败');
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>');
fs.writeFile(path.join(__dirname,'index.html'), newHTML, (err)=>{
if(err) console.log('写入html失败');
console.log('写入html成功');
})
}
三、http模块
服务器与普通电脑的区别就是,服务器上安装了服务器软件,比如IIS、Apache等,通过安装服务器软件,就可以将一台普通电脑变成一台服务器。
node中,我们不需要安装服务器软件,可以使用http模块构建一个web服务器。
1. 创建一个基本的 web 服务器
// 1. 导入http 模块
const http = require('http')
// 2. 创建 web 服务器实例
const server = http.createServer()
// 3. 为服务器实例绑定 request 事件,监听客户端的请求
server.on('request', (req, res) => {
console.log('Someone vist out web server.')
})
// 4. 启动服务器
server.listen(8080, () => {
console.log('server running at http://127.0.0.1:8080')
})
2. req 请求对象
只要服务器接收到了服务器的请求,就会通过调用server.on() 为服务器绑定的 request 事件处理函数。如果想在事件处理函数中,访问与客户端相关的数据或属性,可以使用如下的方式:
const http = require('http')
const server = http.createServer()
// req 是请求对象,包含了与客户端相关的数据和属性
server.on('request', (req) => {
// req.url 是客户端请求的 URL 地址
const url = req.url;
// req.method 是客户端请求的 method 类型
const method = req.method;
const str = `正在请求的url是 ${url},请求方式是${method}`;
console.log(str);
})
server.listen(80, () => {
// 如果端口号是80 服务器网址端口号就可以省略
console.log('server running at http://127.0.0.1')
})
3. res 响应对象
在服务器的request 事件处理函数中,如果想访问与服务器相关的数据或属性,可以使用如下的方法:
server.on('request', (req, res) => {
// req.url 是客户端请求的 URL 地址
const url = req.url;
// req.method 是客户端请求的 method 类型
const method = req.method;
const str = `Your request url is ${url}, and request method is ${method}.`;
const str2 = `你正在请求的url是${url},请求的方式是${method}。`;
// 调用 res.setHeader() 方法,设置 Content-Type 响应头,解决中文乱码问题
res.setHeader('Content-Type', 'text/html; charset=utf-8');
// 调用 res.end() 方法,向客户端响应一些内容
res.end(str + str2);
})
如果响应的数据中包含中文,就会出现中文乱码的问题,解决这个问题,可以调用 res.setHeader() 方法,设置 Content-Type 响应头。
res.setHeader('Content-Type', 'text/html; charset=utf-8');
4. 根据不同的url,响应不同的html
const http = require('http')
const server = http.createServer()
server.on('request', (req, res) => {
// 1. 获取请求的 url 地址
let url = req.url
let content = '<h1>404 Not found!</h1>'
// 2.判断用户请求的是否为 / 或 /index.html 首页 /about.html 关于页面
if(url === '/' || url == '/index.html'){
content = '<h1>首页</h1>'
} else if(url == '/about.html'){
content = '<h1>关于页面</h1>'
}
// 3. 设置 Content-Type 响应头,防止中文乱码
res.setHeader('Content-Type', 'text/html; charset=utf-8')
// 4. 使用 res.end() 把响应内容给客户端
res.end(content)
})
server.listen(8080, () => {
console.log('server running at http://127.0.0.1:8080')
})
5. 总和案例
创建一个服务器,响应客户端请求的资源,我们的电脑既是客户端也是服务器。
const fs = require('fs')
const http = require('http')
const path = require('path')
const server = http.createServer()
server.on('request', (req, res) => {
// 1. 获取 客户端请求的 URL
const url = req.url;
// 2. 把请求的 URL 地址映射为具体文件的存放路径
let fpath = '';
// 2.1 如果客户端请求的url 为 / 默认访问首页
if(url === '/'){
fpath = path.join(__dirname, './index/index.html')
}else {
// 2.2 优化用户请求资源路径
fpath = path.join(__dirname, '/index', url)
}
// 3. 根据映射过来的路径读取文件内容
fs.readFile(fpath, 'utf8', (err, dataStr) => {
// 3.1 读取失败
if(err) return res.end('404 Not found.')
res.end(dataStr)
})
})
server.listen(8080, () => {
console.log('server running at http://127.0.0.1:8080')
})