node.js
查看本机安装的node.js命令:node -v
注意事项:不能使用BOM、DOM的API,顶级对象是global、globalThis(推荐)(这两个相等)
Buffer
缓冲区
本质是一段内存空间,专门用来处理二进制数据。
// 第一种
const bufferOne = Buffer.alloc(10); // 安全,10个字节
// 第二种
const bufferTwo = Buffer.allocUnsafe(10); // 速度快,但不安全可能有旧数据
// 第三种
const bufferThree = Buffer.from("lxh"); // buffer中存储的是十六进制,lxh会转为Unicode编码,再转为十六进制
const bufferFour = Buffer.from([108, 120, 104]); // 这里面的是十进制
bufferFour.toString() // 转为字符串 lxh
bufferFour[0] // 拿到的是十进制 108
bufferThree[0] // 拿到的是十进制 108
bufferThree[0].toString(2) // 拿到的是十进制转二进制 1101100
bufferThree[0] = 95 // 修改 注意这里是十进制,最大255,如果超出,舍去高位的数字(最长8位,多的舍去前面的数字)
const bufferFive = Buffer.from('中国') // 一个汉字站三个字节
运行node
node 路径/文件
使用插件nodemon
安装npm i -g nodemon
nodemon 路径/文件
path模块
const path = require("path");
// __filename、__dirname
// '/a'和'./a'是一样的
path.join('/a', '/b/c', '../', '/d/e/f', '../../')
// 输出 \a\b\d
path.resolve() // 和path.join()差不多
path.basename('/a/b/c/d/e/index.html') // 获取基础名称
// 输出 index.html
path.basename('/a/b/c/d/e/index.html', '.html') // 获取文件名
// 输出 index
path.extname('/a/b/c/d/e/index.html') // 获取扩展名
// 输出 .html
path.parse('../lxh.vue') // 路径信息
// { root: '', dir: '..', base: 'lxh.vue', ext: '.vue', name: 'lxh' }
path.dirname("../lxh/xxx.js") // 获取文件夹名
// ../lxh
fs模块
导出:module.exports
引入:require()
exports和module.exports指向同一个对象
exports和module.exports同时使用时得到的永远是module.exports
注意:为了混乱,建议不同时使用exports和module.exports
exports.age = 24
module.exports = {name: 'xxx'}
// 得到{name: 'xxx'}
module.exports.age = 24
exports = {name: 'xxx'}
// 得到{age: 24}
module.exports.age = 24
exports.name = 'xxx'
// 得到{age: 24, name: 'xxx'}
读取文件
const fs = require("fs");
const path = require("path");
fs.readFile(path.join(__dirname, "demo.txt"), 'utf8', (err, data) => {
if (err) {
console.log(`读取文件失败${err.message}`);
}
console.log(`读取文件成功:${data}`);
});
fs.readFileSync() // 同步
写入文件
const fs = require("fs");
const path = require("path");
// 这种方式是默认是覆盖
// 追加的话写第三个参数{flag: "a"}(一般日志,访问记录用追加)
fs.writeFile(path.join(__dirname, "demo.txt"), {flag: "a"}, "xxxx content", (err) => {
if (err) {
console.log(`写入文件失败${err.message}`);
return
}
console.log(`写入文件成功`);
}); // 异步
fs.writeFileSync() // 同步
追加
const fs = require("fs");
// 注意异步有回调函数,同步没有
fs.appendFile() // 异步
fs.appendFileSync() // 同步
流式
适用于频繁和大文件写入的时候
写入
const path = require("path");
const fs = require("fs");
const _stream = fs.createWriteStream(path.join(__dirname, "lxh.txt"));
_stream.write("你好\r\n")
_stream.write("lxh\r\n")
_stream.close()
读取
const fs = require("fs");
const _read = fs.createReadStream('./lxh.txt', "utf-8")
_read.on('data', chunk => {
console.log(chunk);
})
_read.on("end", () => {
console.log("读取完成");
})
文件移动和重命名
const fs = require("fs");
fs.rename()
fs.renameSync()
文件删除
const fs = require("fs");
fs.unlink()
fs.unlinkSync()
fs.rm()
fs.rmSync()
文件夹的操作
const path = require("path");
const fs = require("fs");
// 创建,{recursive: true}递归创建
fs.mkdir(path.join(__dirname, "a/b/c"), {recursive: true}, (err) => {
if (err) {
console.log("失败", err);
return;
}
console.log("成功");
});
fs.mkdirSync();
// 读取
fs.readdir();
fs.readdirSync();
// 删除
fs.rmdir("/a", {recursive: true}, (err) => {}); // 不推荐,因为{recursive: true}将来会移除
fs.rmdirSync();
fs.rm(); // 建议使用
fs.rmSync();
查看资源状态
const fs = require("fs");
fs.stat('./lxh.txt', (err, data) => {
console.log(data); // 信息
console.log(data.isFile()); // 判断是否是文件
console.log(data.isDirectory()); // 判断是否是文件夹
})
创建基本的web服务器
const http = require("http");
// 创建web服务器实例
const server = http.createServer();
// 为服务器绑定request事件
server.on("request", (req, res) => {
// req.url请求路径、req.method请求类型、req.headers请求头
// res.end向客户端返回数据,英文没有问题,但是中文乱码
// 解决中文乱码下面这句
res.setHeader('content-type', 'text/html;charset=utf-8')
// 获取请求体
let _body = ""
req.on("data", chunk => {
_body += chunk
})
req.on("end", () => {
console.log(_body);
res.end("结束啦")
})
// 获取请求路径和参数
// 方法一
const _urlObj = url.parse(req.url, true);
console.log(_urlObj.pathname);
console.log(_urlObj.query);
// 方法二(推荐)
const _url = new URL(req.url, "http://127.0.0.1");
console.log(_url.pathname);
console.log(_url.searchParams);
console.log(_url.searchParams.get("name"));
res.statusCode = 222; // 设置响应状态码
res.statusMessage = "lxh"; // 设置响应状态描述(中文要报错)
res.write("finished");
res.end();
});
// 监听端口,启动服务器,如果是80,可以省略:80
server.listen(8090, () => {
console.log(`服务器启动了,运行在:http://127.0.0.1:8090`);
});
// 使用插件moment,需要安装
const moment = require("moment");
console.log(moment().format("YYYY-MM-DD HH:mm:ss"));
express
基于 Node.js 平台,快速、开放、极简的 Web 开发框架
安装:npm install express --save
搭建基本服务器
const express = require("express");
const app = express();
app.get("/table", (req, res) => {
// req.query默认是空对象,获取客户端传过来的数据?id='xxx'&search='yyy'
// req.params默认是空对象,获取客户端传过来的数据/:id/:search
// 对象需要JSON转换
res.end(JSON.stringify({ name: "lxh", age: 25 }));
});
app.post("/user", (req, res) => {
res.end("lxh");
});
app.listen(80, () => {
console.log("express server running at http://127.0.0.1");
});
托管静态资源
const express = require("express");
const path = require("path");
const app = express();
// 可以写多个,http://127.0.0.1/lxh.html
app.use(express.static(path.join(__dirname, "/html")));
// http://127.0.0.1/static/lxh.html
app.use('/static', express.static(path.join(__dirname, "/html")));
app.listen(80, () => {
console.log("express server running at http://127.0.0.1");
});
通过html文件夹下面的文件,html目录不存在url中
路由
// 挂在路由
app.post("/user", (req, res) => {
res.end("lxh");
});
// 路由的模块化
新建router.js文件
const express = require("express");
const router = express.Router();
router.get("/user", (req, res) => {
res.end("str");
});
module.exports = router;
注册路由
const router = require(./router.js)
app.use(router)
app.use('/api', router) // 访问需要加前缀/api
中间件
全局中间件,可以定义多个
const mw = (req, res, next) => {
// req.xxx在路由的req可以访问到req.xxx
console.log("中间件");
next(); // 一定要写next()不然请求一直处于加载状态
};
app.use(mw)
局部中间件,可以写多个
const mw = (req, res, next) => {
console.log("中间件");
next();
};
app.get("/xxx", mw, (req, res) => {
res.end("局部");
});
// 定义多个局部中间件
app.get("/xxx", mw1,mw2, (req, res) => {
res.end("局部");
});
app.get("/xxx", [mw1,mw2], (req, res) => {
res.end("局部");
});
错误级别的中间件多一个参数
app.use((err, req, res, next) => {
console.log(`发送错误:${err.message}`)
next()
})
// 注意:错误级别的中间件必须放到所有路由之后
内置的中间件
express.static()
express.json()
express.urlencoded()
配置解析application/json格式数据的内置中间件
app.use(express.json())
配置解析application/x-www-form-urlencoded 格式数据的内置中间件
app.use(express.urlencoded({ extended: false }))
// 这俩个通过req.body获取客户端传过来的数据
第三方中间件
body-parser
需要安装
const bp = require('body-parser')
app.use(bp.json())
app.use(bp.urlencoded({extended: false}))
解决跨域
cors有一系列http响应头组成,配置cors相关的响应头就能解决跨域
使用cors中间件,安装npm i cors
const cors = require('cors')
app.use(cors())
cors三个响应头
Access-Control-Allow-Origin
res.setHeader('Access-Control-Allow-Origin', '*')
Access-Control-Allow-Headers
res.setHeader('Access-Control-Allow-Headers', 'Content-type, X-Custom-Heaher')
Access-Control-Allow-Methods
// 默认情况仅支持GET、POST、HEAD请求
res.setHeader('Access-Control-Allow-Methods', '*')
koa
基于Node.js平台的下一代web框架
安装:npm i koa
搭建基本服务器
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(80, () => {
console.log(`koa server running at http://127.0.0.1`)
});
路由
安装:npm i koa-router
const Koa = require('koa');
const Router = require('koa-router')
const app = new Koa();
const router = new Router({prefix: '/xxx'}); // prefix前缀
router.get(`/`, async (ctx) => {
// ctx里包括request、response
ctx.body = '首页'
})
app.use(router.routes());
app.listen(80, () => {
console.log(`koa server running at http://127.0.0.1`)
});
跨域
安装:npm i koa2-cors
const cors = require('koa2-cors')
app.use(cors())