Buffer 是一个类似于数组的 对象 ,用于表示固定长度的字节序列。
Buffer 本质是一段内存空间,专门用来处理 二进制数据 。
//创建了一个长度为 10 字节的 Buffer,相当于申请了 10 字节的内存空间,每个字节的值为 0
let buf_1 = Buffer.alloc(10); // 结果为
//创建了一个长度为 10 字节的 Buffer,buffer 中可能存在旧的数据, 可能会影响执行结果,所以叫unsafe
let buf_2 = Buffer.allocUnsafe(10);
//通过字符串创建 Buffer
let buf_3 = Buffer.from('hello');
//通过数组创建 Buffer
let buf_4 = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117]);
toString
方法将 Buffer
转为字符串。toString
默认是按照 utf-8
编码方式进行转换的。let buf_4 = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117]);
console.log(buf_4.toString())
//读取
console.log(buf_3[1]);
//修改
buf_3[1] = 97;
//查看字符串结果
console.log(buf_3.toString());
注意:
fs.writeFileSync(文件名,待写入的数据[,选项设置 可选])
fs.writeFile(文件名,待写入的数据[,选项设置 可选],回调函数)
该函数的第三个参数设置为{flag: 'a'}
可以实现追加写入const fs = require('fs');
fs.writeFile('./座右铭.txt', '三人行,则必有我师', err=>{
if (err) {
console.log('写入失败');
return;
}
console.log('写入成功', err); // 写入成功 null
})
fs.appendFile(文件名, 待写入数据[, options], 回调)
fs.appendFileSync(文件名, 待写入数据[, options])
// 1. 引入fs模块
const fs = require('fs');
// 2. 调用方法
fs.appendFile('./座右铭.txt', ',则其善者而从之,其不善者而改之', err => {
if (err) {
console.log('追加失败');
return;
}
console.log('追加成功');
});
// fs 中使用 \r\n 实现换行
fs.appendFileSync('./座右铭.txt', '\r\n温故而知新,可以为师矣');
// writeFile 可以实现追加写入,将第三个参数设置为: {flag: 'a'}
fs.writeFile('./座右铭.txt', '\r\n一闪一闪亮晶晶', { flag: 'a' }, err => {
if (err) {
console.log('追加失败');
return;
}
console.log('追加成功');
});
fs.createWriteStream(path[, options])
// 流式写入 适合 大文件写入或者频繁写入,writeFile 适合写入频率较低的场景
// 1. 导入 fs
const fs = require('fs');
// 2. 创建写入流对象 fs.createWriteCream(文件[,option])
const ws = fs.createWriteStream('./静夜思.txt');
// 3. write() 写入
ws.write('床前明月光\r\n');
ws.write('疑是地上霜\r\n');
ws.write('举头望明月\r\n');
ws.write('低头思故乡\r\n');
// 4. 关闭通道
ws.close(); // close() 是可选的,可以不加
readFile(文件[,option],回调函数(a, b))
,回调函数两个参数。 fs.readFileSync(path[, options])
// 需求:读取文件静夜思.txt的内容,并输出
// 1. 引入fs模块
const fs = require('fs');
// 2. 异步读取 readFile(文件[,option],回调函数(a, b)) 回调函数两个参数
fs.readFile('./静夜思.txt', (err, data) => {
if (err) {
console.log('读取失败');
return;
}
console.log(data);
console.log(data.toString());
});
// 3. 同步读取 readFileSync()
let data = fs.readFileSync('./静夜思.txt');
console.log(data);
console.log(data.toString());
fs.createReadStream(path[, options])
// createReadStream 大文件,提高效率
// 1. 引入 fs 模块
const fs = require('fs');
// 2. 创建读取流对象
const rs = fs.createReadStream('./笑看风云.mp4');
// 3. 绑定 data 事件 ,每次取出 64k 数据后执行一次 data 回调
rs.on('data', data => {
console.log(data);
console.log(data.length); // 65536字节 => 64KB
});
// end 事件,可选事件,读取完毕后, 执行 end 回调
rs.on('end', () => {
console.log('读取完成');
});
// 需求: 复制 笑看风云.mp4
const fs = require('fs');
const process = require('process');
// (1)readFile
// 读取文件内容
// const data = fs.readFileSync('笑看风云.mp4');
// 写入文件
// fs.writeFileSync('./笑看风云2.mp4', data);
// console.log(process.memoryUsage()); // rss: 112545792字节
// (2)createReadStream 流式
// 创建读取流对象
const rs = fs.createReadStream('笑看风云.mp4');
// 创建写入流对象
const ws = fs.createWriteStream('./笑看风云3.mp4');
// 绑定 data 事件
rs.on('data', chunk => {
ws.write(chunk);
});
rs.on('end', () => {
console.log(process.memoryUsage()); // 获得代码运行的内存占用量。rss: 50831360字节
});
// rs.pipe(ws); // 也是文件复制
fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)
// 重命名、文件移动,都是改变了 文件的路径
// (1) fs.rename(old, new, callback())
const fs = require('fs');
fs.rename('座右铭.txt', './论语.txt', err => {
if (err) {
console.log('重命名失败');
return;
}
console.log('重命名成功');
});
// 文件的移动
fs.rename('data.txt', '资料/data.txt', err => {
if (err) {
console.log('文件移动失败');
return;
}
console.log('文件移动成功');
});
// (2) fs.renameSync(old, new)
const fs = require('fs');
fs.renameSync('论语.txt', '座右铭.txt');
fs.unlink(path, callback)
、fs.unlinkSync(path)
同步fs.rm(path, callback)
、fs.rmSync(path)
// 1. unlink(path, callback()) unlinkSync(path) 同步
const fs = require('fs');
fs.unlink('./静夜思.txt', err => {
if (err) {
console.log('删除失败');
return;
}
console.log('删除成功');
});
// 2. rm 方法 fs.rm(path, callback()) rmSync(path) 同步
fs.rm('./座右铭.txt', err => {
if (err) {
console.log('删除失败');
return;
}
console.log('删除成功');
})
fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])
// 创建文件夹 fs.mkdir(path[, options], callback) m make dir directory fs.mkdirSync(path[, options])同步
fs.mkdir('./html', err => {
if (err) {
console.log('创建失败');
return;
}
console.log('创建成功');
});
// 递归创建
fs.mkdir('./a/b/c',{recursive: true}, err => {
if (err) {
console.log('创建失败');
return;
}
console.log('创建成功');
});
fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])
fs.readdir('./资料', (err, data) => {
if (err) {
console.log('读取失败');
return;
}
console.log(data);
});
fs.readdir('./', (err, data) => {
if (err) {
console.log('读取失败');
return;
}
console.log(data);
});
fs.rmdir(path[, options], callback)
fs.rmdirSync(path[, options])
// 删除文件夹 fs.rmdir(path[, options], callback) fs.rmdirSync(path[, options])
fs.rmdir('./html', err => {
if (err) {
console.log('删除失败');
return;
}
console.log('删除成功');
});
// 递归删除
fs.rmdir('./a', {recursive: true}, err => { // 不推荐使用
if (err) {
console.log('删除失败');
return;
}
console.log('删除成功');
});
fs.rm('./a', { recursive: true }, err => {
if (err) {
console.log('删除失败');
return;
}
console.log('删除成功');
});
fs.stat(path[, options], callback)
fs.statSync(path[, options])
//异步获取状态
const fs = require('fs');
fs.stat('./资料/笑看风云.mp4', (err, data) => {
if (err) {
console.log('操作失败');
return;
}
console.log(data);
// isFile 文件
console.log(data.isFile()); // true
// isDirectory() 文件夹
console.log(data.isDirectory()); // false
});
//同步获取状态
let data = fs.statSync('./data.txt');
./座右铭.txt
当前目录下的座右铭.txt座右铭.txt
等效于上面的写法../座右铭.txt
当前目录的上一级目录中的座右铭.txtD:/Program Files
windows 系统下的绝对路径/usr/bin
Linux 系统下的绝对路径API | 说明 |
---|---|
path.resolve | 拼接规范的绝对路径 |
path.sep | 获取操作系统的路径分隔 |
path.parse | 解析路径并返回对象 |
path.basename | 获取路径的基础名称 |
path.dirname | 获取路径的目录名 |
path.extname | 获取路径的扩展名 |
const fs = require('fs');
const path = require('path');
fs.writeFileSync(__dirname + '/index.html', 'love');
console.log(__dirname + '/index.html');
// path.resolve 拼接规范的绝对路径 ./index.html == index.html
// path.resolve(绝对路径,相对路径)
console.log(path.resolve(__dirname, './index.html')); // D:\QD\nodejs\03-_path模块\index.html
// path.sep 获取操作系统的路径分隔符
console.log(path.sep); // \
// path.parse 解析路径并返回对象
// __filename “全局变量”,保存文件的绝对路径
console.log(__filename); // D:\QD\nodejs\03-_path模块\path.js
let str = 'D:\\QD\\nodejs\\03-_path模块\\path.js';
console.log(path.parse(str));
console.log(path.basename(str)); // path.js 获取文件名
console.log(path.dirname(str)); // D:\QD\nodejs\03-_path模块 获取文件夹名字
console.log(path.extname(str)); // 获取扩展名 .js
本地回环IP地址: 127.0.0.1 ~ 127.255.255.254
// 1. 导入 http 模块
const http = require('http');
// 2. 创建服务对象 createServer(function(请求,响应){}) 函数在接收到请求时执行
// 第一个实参:对象,请求报文的封装对象
// 第二个实参:对象,响应报文的封装
const server = http.createServer((request, response) => {
// response.end('hello HTTP'); // 设置响应体 并结束响应
response.setHeader('content-type', 'text/html;charset=utf-8'); // 响应内容中文代码的解决办法 response.setHeader('content-type', 'text/html;charset=utf-8')
response.end('你好');
});
// 3. 监听端口,启动服务
server.listen(9000, () => { // 当服务启动成功以后执行
console.log('服务已经启动'); // 当服务启动后,更新代码必须重启服务才能生效
});
// Ctrl + c ,停止服务
// HTTP协议默认端口是80,HTTPS协议的默认端口是443
// 端口被其他程序占用,在资源监视器找到占用端口的程序 使用任务管理器关闭对应的程序
含义 | 语法 |
---|---|
请求方法 | request.method |
请求版本 | request.httpVersion |
请求路径 | request.url |
URL路径 | request(‘url’).parse(request.url).pathname |
URL查询字符串 | request(‘url’).parse(request.url, true).query |
请求头 | request.headers |
请求体 | request.on(‘data’, function(chunk(){})) ,request.on(‘end’, function(){}) |
// 1. 导入 http 模块
const http = require('http');
// 2. 创建服务对象 createServer(function(请求,响应){}) 函数在接收到请求时执行
const server = http.createServer((request, response) => {
// 获取请求的方法
console.log(request.method); // GET
// 获取请求的url
console.log(request.url); // localhost:9000 只包含路径与查询字符串
// 获取HTTP协议的版本号
console.log(request.httpVersion); // 1.1
// 获取HTTP的请求头(返回一个对象)
console.log(request.headers);
console.log(request.headers.host);
response.end('http'); // 设置响应体
});
// 3. 监听端口,启动服务
server.listen(9000, () => { // 当服务启动成功以后执行
console.log('服务已经启动');
});
// 1. 导入 http 模块
const http = require('http');
// 2. 创建服务对象 createServer(function(请求,响应){}) 函数在接收到请求时执行
const server = http.createServer((request, response) => {
// (1) 声明一个变量
let body = '';
// (2) 绑定data事件
request.on('data', chunk => { // chunk 就是 Buffer,会自动转换为字符串
body += chunk;
});
// (3) 绑定end事件
request.on('end', () => { // 数据读完触发
console.log(body);
// 响应
response.end('HELLO HTTP');
});
});
// 3. 监听端口,启动服务
server.listen(9000, () => {
console.log('服务已经启动');
});
// 导入 http 模块
const http = require('http');
// 1. 导入 url 模块
const url = require('url');
// 创建服务对象 createServer(function(请求,响应){}) 函数在接收到请求时执行
const server = http.createServer((request, response) => {
// 2. 解析 request.url
let res = url.parse(request.url, true); // 第二个参数设为true,则res.query属性结果为对象
// console.log(res);
// 路径 res.pathname
let pathname = res.pathname;
// 查询字符串
let keyword = res.query.keyword; // 属性名 => 键
response.end('url');
});
// 监听端口,启动服务
server.listen(9000, () => {
console.log('服务已经启动');
});
// 导入 http 模块
const http = require('http');
// 创建服务对象 createServer(function(请求,响应){}) 函数在接收到请求时执行
const server = http.createServer((request, response) => {
// 实例化 url 对象
// let url = new URL('http://www.xxxx.com/search?a=100&b=200');
// let url = new URL('/search?a=100&b=200','http://www.xxxx.com');
// console.log(url);
let url = new URL(request.url, 'http://127.0.0.1:9000');
// 输出路径 url.pathname
console.log(url.pathname);
// 输出keyword查询字符串 url.searchParams.get('键名')
console.log(url.searchParams.get('keyword'));
response.end('url new');
});
// 监听端口,启动服务
server.listen(9000, () => {
console.log('服务已经启动');
});
作用 | 语法 |
---|---|
设置响应状态码 | response.statusCode |
设置响应状态描述 | response.statusMessage |
设置响应头信息 | response.setHeader(‘头名’,‘头值’) |
设置响应体 | response.write(‘xx’), response.end(‘xx’) |
解决中文乱码问题 : response.setHeader("Content-Type","text/html;charset=utf-8")
1
// 导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => { // 有 而且 只能有一个 response.end()
// 1. 设置响应状态码(默认200) response.statusCode =
response.statusCode = 203;
// 2. 设置响应状态描述 response.statusMessage (用的特别少)
response.statusMessage = 'abcd';
// 3. 设置响应头信息 response.setHeader('头名', '头值') response.setHeader('content-type','text/html;charset=utf-8')
response.setHeader('myHeader','test test test');
response.setHeader('test', ['a', 'b', 'c']); // 设置多个同名的响应头
// 4. 设置响应体 response.write('xx') response.end('xxx');
response.write('love'); // 如果使用了write一般就不再用end , write()可以多次调用
response.write('love');
response.write('love');
response.write('love');
response.end('HTTP');
});
// 监听端口,启动服务
server.listen(9000, () => {
console.log('服务器已启动,端口9000监听中');
});
const http = require('http');
const fs = require('fs');
const server = http.createServer((request, response) => {
let html = fs.readFileSync('./09表格.html'); // 读取文件内容
response.end(html); // end 参数可以是字符串或Buffer
});
server.listen(9000, () => {
console.log('服务已经启动,端口9000正在监听中');
});
application/json
html: 'text/html',
css: 'text/css',
js: 'text/javascript',
png: 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
mp4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json'
对于未知的资源类型,可以选择 application/octet-stream
类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是我们常见的 下载 效果。 response.setHeader('content-type', 'application/octet-stream;charset=utf-8');
GET 和 POST 是 HTTP 协议请求的两种方式:
模块化
。每个文件就是一个模块
,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用。1. 创建 me.js
//声明函数
function tiemo(){
console.log('贴膜....');
}
//暴露数据
module.exports = tiemo;
2. 创建 index.js
//导入模块
const tiemo = require('./me.js');
//调用函数
tiemo()
module.exports = value
可以暴露任意数据。exports.name = value
// 声明一个函数
function tiemo() {
console.log('贴膜');
}
function chifan() {
console.log('吃饭');
}
// 暴露数据
// module.exports = {
// tiemo,
// chifan
// }
// exports 暴露数据
// exports.tiemo = tiemo;
// exports.chifan = chifan;
// 1. module.exports 可以暴露 任意 数据
// module.exports = 'iloveyou';
// module.exports = '522';
// 2. 不能使用 exports = value 的形式暴露数据,模块内部 module 与 exports 的隐式关系
// exports = 'i'; 是错误的
// exports = module.exports = {} ,require 返回的是目标模块中 module.exports 的值
// console.log(module.exports); // {}
// console.log(module.exports == exports); // true
在模块中使用 require 传入文件路径即可引入文件。
const test = require('./me.js');
require 使用的一些注意事项:
js
和 json
文件导入时可以不用写后缀,c/c++编写的 node 扩展文件也可以不写后缀,但是一般用不到。如果js和json文件同名,并且省略后缀导入,则先导入js文件。js
文件进行处理package.json
文件中 main
属性对应的文件,main
属性不存在,或者 package.json
不存在,则会尝试导入文件夹下的 index.js
和index.json
,如果还是没找到,就会报错npm
-g
,npm i -g nodemonpackage.json
中的scripts
属性{
"scripts": {
"server": "node server.js",
"start": "node index.js"
}
}
如上配置完之后,可以使用npm run server
、npm run start
(npm start
)
2. cnpm
和npm
切换使用
npm
切换为 cnpm
npm config set registry https://registry.npm.taobao.org
npm config get registry
,成功则显示https://registry.npm.taobao.org/
cnpm
切换为 npm
npm config set registry https://registry.npmjs.org
npm config get registry
,成功则显示https://registry.npmjs.org/
// 1. 导入 express
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由
app.get('/home', (request, response) => {
response.end('express,hello');
});
// 4. 监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000正在监听中...');
});
路由确定了应用程序如何响应客户端对特定端点的请求。
请求方法、路径、回调函数
app.方法(path, callback)
// 导入 express
const express = require('express');
// 创建应用对象
const app = express();
// 创建路由
app.get('/home', (request, response) => {
response.end('hello,Express');
});
app.get('/', (request, response) => {
response.setHeader('content-type', 'text/html;charset=utf-8');
response.end('首页');
});
app.post('/login', (request, response) => {
response.setHeader('content-type', 'text/html;charset=utf-8');
response.end('登录');
});
app.all('/test', (request, response) => { // 匹配所有请求方法,get post
response.end('test test');
});
app.all('*', (request, response) => { // 自定义 404 路由
response.end('404 Not Found
');
});
// 监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口 3000 正在监听中');
});
//导入 express
const express = require('express');
//创建应用对象
const app = express();
//获取请求的路由规则
app.get('/request', (req, res) => {
//1. 获取报文的方式与原生 HTTP 获取方式是兼容的
console.log(req.method);
console.log(req.url);
console.log(req.httpVersion);
console.log(req.headers);
//2. express 独有的获取报文的方式
console.log(req.path); // 获取路径
console.log(req.query); // 获取查询字符串
console.log(req.ip); // 获取客户端的IP地址
console.log(req.get('host')); // 获取指定的请求头
res.send('请求报文的获取');
});
//启动服务
app.listen(3000, () => {
console.log('启动成功....')
})
req.params.id
=> 获取路由参数id
路由参数指的是 URL 路径中的参数(数据)。
app.get('/:id.html', (req, res) => {
res.send('商品详情, 商品 id 为' + req.params.id);
});
const express = require('express');
const app = express();
app.get('/response', (req, res) => {
// 1. 原生响应设置
res.statusCode = 404; // 设置响应状态码
res.statusMessage = '123'; // 设置响应状态描述
res.setHeader('abc', 'xyz'); // 设置响应头
res.write('hello Express'); // 设置响应体
res.end('response'); // 设置响应体
// 2. express 响应方法
// res.status(500); // 设置响应状态码
// res.set('aaa', 'bbb'); // 设置响应头
// res.send('你好 express'); // 设置响应体
res.status(500).set('aaa', 'ddd').send('你好Express');
});
app.listen(3000, () => {
console.log('服务已经启动,端口 3000 正在监听中');
});
const express = require('express');
const app = express();
app.get('/other', (req, res) => {
res.redirect('https://www.baidu.com'); // 重定向 跳转响应
res.download(__dirname + '/package.json'); // 下载响应,传入文件的绝对路径
res.json({
name: 'yuzuru',
slogon: '努力'
}); // json响应
res.sendFile(__dirname + '/test.html'); // 响应文件test.html中的内容
});
app.listen(3000, () => {
console.log('服务已经启动,端口 3000 正在监听中');
});
本质是一个回调函数
。使用函数封装公共操作,简化代码
// 需求:记录每个请求的 url 与 IP 地址
const express = require('express');
const path = require('path');
const fs = require('fs');
const app = express();
// 声明中间件函数
function recordMiddleware(req, res, next) {
let {url, ip} = req; // 获取 url ip
fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip}\r\n`); // 将信息保存在文件 access.log
next(); // 调用next
}
// 使用中间件函数
app.use(recordMiddleware);
app.get('/home', (req, res) => {
res.send('前台首页');
});
app.get('/admin', (req, res) => {
res.send('后台首页');
});
app.all('*', (req, res) => {
res.send('404 Not Found
');
});
app.listen(3000, () => {
console.log('服务已经启动,端口 3000 正在监听中');
});
app.get('/路径',
中间件函数, (request, response) => {});
app.get('/路径',
中间件函数1,
中间件函数2, (request, response) => {});
// 需求:/admin /setting 的请求,要求 URL 携带 code=521 参数,如未携带 提示 【暗号错误】
const express = require('express');
const app = express();
function checkCodeMiddleware(req, res, next) {
if (req.query.code === '521') { // 判断URL code是否等于521
next();
} else {
res.send('【暗号错误】');
}
}
app.get('/setting', checkCodeMiddleware, (req, res) => {
res.send('设置页面');
});
app.get('/admin', checkCodeMiddleware, (req, res) => {
res.send('后台首页');
});
app.all('*', (req, res) => {
res.send('404 Not Found
');
});
app.listen(3000, () => {
console.log('服务已经启动,端口 3000 正在监听中');
});
//引入express框架
const express = require('express');
//创建服务对象
const app = express();
app.use(express.static(__dirname + '/public')); // 静态资源中间件设置
//如果访问的内容经常变化,还是需要设置路由
//但是,在这里有一个问题,如果public目录下有index.html文件,单独也有index.html的路由,则谁书写在前,优先执行谁
app.get('/index.html', (request, response) => {
response.send('首页');
});
//监听端口
app.listen(3000, () => {
console.log('3000 端口启动....');
});
body-parser
npm i body-parser
const bodyParser = require('body-parser');
//处理 querystring 格式的请求体
let urlParser = bodyParser.urlencoded({extended:false});
//处理 JSON 格式的请求体
let jsonParser = bodyParser.json();
urlParser
,然后使用 request.body 来获取请求体数据app.post('/login', urlParser, (request,response)=>{
//console.log(request.body); //获取请求体数据
console.log(request.body.username); //用户名
console.log(request.body.userpass); //密码
response.send('获取请求体数据');
});
示例:
// 需求: GET /login 显示表单网页
// POST /login 获取表单中的 用户名 和 密码
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
// 解析json格式的请求体的中间件
const jsonParser = bodyParser.json();
// 解析 querystring 格式请求体的中间件
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.get('/login', (req, res) => {
// res.send('表单页面');
// 响应 HTML 文件内容
res.sendFile(__dirname + '/11_form.html');
});
app.post('/login', urlencodedParser, (req, res) => {
// 获取用户名和密码 中间件函数执行完毕以后,会往请求对象身上添加body属性
console.log(req.body);
res.send('获取用户的数据');
});
app.listen(3000, () => {
console.log('服务已经启动,端口 3000 正在监听中');
});
const express = require('express');
const app = express();
// 声明中间件
app.use((req, res, next) => {
// 检测请求头中的 referer 是否为 127.0.0.1
let referer = req.get('referer');
if (referer) {
// 实例化
let url = new URL(referer);
console.log(url);
// 获取hostname
let hostname = url.hostname;
console.log(hostname); // 127.0.0.1 localhost
// 判断
if (hostname != '127.0.0.1') {
// 响应404
res.status(404).send('404 Not Found
');
return;
}
}
next();
});
// 静态资源中间件设置
app.use(express.static(__dirname + '/public'));
app.listen(3000, () => {
console.log('服务已经启动,端口 3000 正在监听中');
});
express.Rounter()
homeRouter.js
// 1. 导入express
const express = require('express')
// 2. 创建路由器对象
const router = express.Router();
// 3. 在router对象身上添加路由
router.get('/setting', (req, res)=>{
res.send('设置页面');
})
router.get('/admin', (req, res)=>{
res.send('后台首页');
})
// 4. 暴露router对象
module.exports = router;
const express = require('express');
const app = express();
// 5. 引入子路由文件
const homeRouter = require('./routes/homeRouter.js');
// 6. 设置和使用中间件
app.use(homeRouter);
app.all('*', (req, res)=>{
res.send('404 NOT FOUND
');
})
app.listen(3000, ()=>{
console.log('服务已经启动');
})
模板引擎
是分离用户界面和业务数据
的一种技术。EJS
模板引擎npm i ejs --save
// js文件 ,实现列表渲染
const ejs = require('ejs');
const fs = require('fs');
const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧'];
/*
<% xiyou.forEach(item => { %>
- <%= item %>
<% }) %>
*/
// <% %> 可以对 <% %>包含的js代码执行,forEach可以进行循环处理
// EJS 实现
let str = fs.readFileSync('./02_xiyou.html').toString();
let result = ejs.render(str, {xiyou: xiyou});
console.log(result);
// html文件
Document
西游
<% xiyou.forEach(item => { %>
- <%= item %>
<% }) %>
(2)条件渲染
// js 文件
const ejs = require('ejs');
const isLogin = true;
const result = ejs.render(
`
<% if(isLogin){ %>
欢迎回来
<% }else {%>
<% } %>
`, { isLogin: isLogin }
)
console.log(result);
<% %>
: JS代码<%= %>
: 转义的数据(<%= item %>
)<%- %>
: 非转义的数据