Node.js 是一个开源和跨平台的 JavaScript 运行时环境。Node.js 在浏览器之外运行 V8 JavaScript 引擎(Google Chrome 的内核)
特点
学习 Node.js 可以深入理解服务器开发、Web 请求和响应过程、了解服务器端如何与客户端配合
REPL 全称:Read-Eval-Print-Loop(交互式解释器)
R:读取, E:执行, P:打印,L:循环
控制台输入 node 命令进入 REPL 环境,两次 Ctrl + C 退出 REPL 环境
执行 js 文件
文件读写:需要用到 fs 模块, 加载 fs 模块,: const fs = require('fs');
写文件:
fs.writeFile(file, data[, options], callback)
const fs = require("fs");
fs.writeFile("./file.txt", "Hello World!", "utf-8", (err) => {
if (err) {
console.log("写文件出错,具体错误:", err);
} else {
console.log("ok");
}
});
读文件:
fs.readFile(path[, options], callback)
const fs = require("fs");
fs.readFile("./file.txt", "utf-8", (err, data) => {
if (err) {
console.log("读文件错误");
} else {
console.log(data);
}
});
__dirname: 当前模块的目录名
__filename: 当前模块的文件名
path 模块:用于文件路径的拼接
// 1. 加载http模块
const http = require("http");
// 2. 创建http服务
const server = http.createServer();
// 3. 为http服务对象添加request事件
server.on("request", (req, res) => {
res.setHeader("Content-Type", "text/html;charset=utf-8"); // 通过setHeader()来设置内容类型,让浏览器可以识别不同类型的文件
res.write("Hello World! <h1>你好</h1>"); // 向请求的客户端发送响应内容
res.end(); // 结束响应
});
// 开启http服务监听
server.listen(8080, () => {
console.log("请访问:http://localhost:8080");
});
实现进入首页出来首页的结构,进入其他页面出来 404 页面。现在不支持加载 html 文件中的其他文件,如 css 文件、图片等
const http = require("http");
const fs = require("fs");
const path = require("path");
const server = http
.createServer((req, res) => {
if (req.url === "/" || req.url === "/index") {
fs.readFile(path.join(__dirname, "htmls", "index.html"), (err, data) => {
if (err) {
throw err;
}
res.end(data);
});
} else {
fs.readFile(path.join(__dirname, "htmls", "404.html"), (err, data) => {
if (err) {
throw err;
}
res.end(data);
});
}
})
.listen("8080", (err) => {
if (err) {
console.log(err);
} else {
console.log("ok");
}
});
实现加载 css 文件等,就是在判断条件中增加判断 css 的条件,并且设置响应头中的 Content-Type 为 text/css 即可,图片等文件同理
const http = require("http");
const fs = require("fs");
const path = require("path");
const server = http
.createServer((req, res) => {
if (req.url === "/register") {
fs.readFile(
path.join(__dirname, "htmls", "register.html"),
(err, data) => {
if (err) {
throw err;
} else {
res.end(data);
}
}
);
} else if (req.url === "/css/register.css") {
fs.readFile(
path.join(__dirname, "htmls", "css", "register.css"),
(err, data) => {
if (err) {
throw err;
} else {
res.setHeader("Content-Type", "text/css");
res.end(data);
}
}
);
} else {
fs.readFile(path.join(__dirname, "htmls", "404.html"), (err, data) => {
if (err) {
throw err;
} else {
res.end(data);
}
});
}
})
.listen(8080, (err) => {
if (err) {
throw err;
} else {
console.log("ok");
}
});
通过npm install mime
,然后使用 mime 模块优化上面的代码(上面的代码很多可复用的部分没有分离出来)
通过npm 官网可以查看 mime 的用法
下面用到的用法:mime.getType(filePath)根据文件路径可以得到 Content-Type。
const http = require("http");
const path = require("path");
const fs = require("fs");
const mime = require("mime");
const server = http
.createServer((req, res) => {
const filePath = path.join(__dirname, "public", req.url);
fs.readFile(filePath, (err, data) => {
if (err) {
res.end("文件不存在 404");
} else {
res.setHeader(
"Content-Type",
mime.getType(filePath) + ";charset=utf-8;"
);
res.end(data);
}
});
})
.listen(8080, (err) => {
if (err) {
throw err;
} else {
console.log("ok");
}
});
第一个参数是 url,第二个参数为 true 时,可以把查询字符串的参数部分变为对象形式,如下图所示
第二个参数不是 true(默认为 false)时
const _ = require("underscore");
const html = "<h2><%= name %></h2>"; // 类似vue的插值表达式{{}}
const f = _.template(html);
console.log(
f({
name: "clz",
})
);
事件驱动程序:
Node.js 使用事件驱动模型,当 web server 接收到请求,就会把请求关闭,进行处理,然后去服务下一个 web 请求。当请求完成,它会被放回处理队列,当到达队列开头,结果会被返回给用户。
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时会触发回调函数。
图片来源:菜鸟教程
const events = require("events");
const eventEmitter = new events.EventEmitter(); // 创建eventEmitter对象
const connectHandler = function connected() {
console.log("连接成功");
eventEmitter.emit("data_received");
};
eventEmitter.on("connection", connectHandler); // 绑定事件connection事件处理程序
eventEmitter.on("data_received", () => {
console.log("数据接收成功");
});
eventEmitter.emit("connection"); // 触发connection事件
console.log("程序执行完毕");
图片来自菜鸟教程
在路径 Y 下执行 require(X)语句执行顺序:
load_as_file(X):
load_as_directory(Y + X):
load_index(X):
使用 Node 创建 web 服务器
const http = require("http");
const fs = require("fs");
http
.createServer((req, res) => {
fs.readFile(__dirname + "/index.html", (err, data) => {
if (err) {
throw err;
} else {
res.writeHead(200, {
"Contnet-Type": "text/html",
});
res.write(data.toString());
}
res.end();
});
})
.listen(9090, (err) => {
if (err) {
throw err;
} else {
console.log("http://localhost:9090");
}
});
在该目录下创建一个 index.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Server</title>
</head>
<body>
<h2>CLZ</h2>
<p>CZH</p>
</body>
</html>
执行 server.js 文件
使用 Node 创建 web 客户端
const http = require("http");
const options = {
// 用于请求的选项
host: "localhost",
port: "9090",
path: "/index.html",
};
const callback = function (res) {
// 处理响应的回调函数
let body = "";
res.on("data", function (data) {
body += data;
});
res.on("end", function () {
console.log(body);
});
};
const req = http.request(options, callback);
req.end();
新开一个终端, 执行 client.js 文件
Express 框架的核心特性:
npm install express -S
几个重要的模块
实例 1:
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("Hello World!");
});
const server = app.listen(9090, "localhost", function () {
let host = server.address().address;
let port = server.address().port;
console.log(server.address());
console.log("http://%s:%s", host, port);
});
执行以上代码后,在浏览器中访问 http://localhost:9090/
实例 2(路由):
const express = require("express");
const app = express();
app.get("/", function (req, res) {
res.send("Hello");
});
app.get("/list_user", function (req, res) {
res.send("用户列表页面");
});
app.get("/ab*cd", function (req, res) {
res.send("正则匹配");
});
const server = app.listen(9090, function () {
console.log("http://localhost:9090");
});
实例 3(静态资源):
const express = require("express");
const app = express();
app.use(express.static("public")); // 实现可以加载public目录下的静态资源文件
app.get("/", function (req, res) {
res.send("Hello");
});
const server = app.listen(9090, function () {
console.log("http://localhost:9090");
});
npm install mysql
const mysql = require("mysql");
const connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "******", // 自己的密码
database: "node_mysql",
});
connection.connect();
connection.query("select 1 + 1 as solution", function (err, results, fields) {
if (err) {
throw err;
}
console.log("The solution is: " + results[0].solution);
});