核心模块
http
帮助我们启动服务器或执行发送请求等其他任务。
const http = require("http");
导入模块,它会自动在全局模块(这是在 node.js 中自带的模块)中寻找。
createServer()
创建服务器并返回 server 对象。接收一个函数作为参数,每当有请求时就会执行这个函数。函数有两个默认参数——请求的信息,和响应的信息:
const server = http.createServer((req, res) => {
// req:包含请求的详细信息
console.log(req.url); // 发起请求的地址(http://localhost:3000/后的地址)
console.log(req.method); // 请求方法(GET/POST等)
console.log(req.headers); // 请求头信息
// res:服务端响应回去的对象
res.setHeader("Content-Type", "text/html"); // 设置响应头(响应的文本为HTML)
// 写入文本信息(此处为HTML)
res.write("<html>");
res.write("<head><title>First page</title></head>");
res.write("<body><h1>Hello,Node.js</h1></body>");
res.write("</html>");
res.end(); // 结束编写,发送响应给浏览器(此后的写入无效)
});
server.listen(3000);
注意:
res.write()也可以使用模板字符串直接写入。
我们可以通过这个返回的 server 对象来对 server 进行操作:
**listen()**:确保 node.js 不会立刻退出我们的代码,而是通过
listen()保留它的进程。listen()有几个参数:第一个参数:需要监听的端口号;
一般在生产环境中不需要填写,默认端口为 80;如果本地开发则可能需要不同的端口。
server.listen(3000);现在启动 node.js 执行文件后,node.js 可以监听到访问本地 3000 地址后的请求,然后执行
createServer()的里的函数。
https
帮助我们启动一个 SSL 加密的服务器。
fs
帮助我们操作文件,对文件进行读写操作。
const fs = require("fs");
writeFile()
写入一个文件,接收三个参数:
- 第一个参数:完整文件名
- 第二个参数:文件内容
- 第三个参数:回调函数,接收一个 error 对象,如果执行出现错误可以在这里得到
fs.writeFile("message.txt", "ds");
writeFileSync()
同步写入文件,在写入文件完成后才能执行下一步。用法与writeFile()相同。
readFile()
读取指定路径的文件,接收两个参数:
- 第一个参数:文件路径
- 第二个参数:回调函数,接收一个读取错误时的对象(error 对象)和文件内容
fs.readFile(path, (err, fileContent) => {});
path
帮助我们构建文件路径,让文件的路径能够在任何操作系统(Windows/Mac/Linux)上运行。
const path = require("path");
join()
使用特定于平台的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。
path.join("/foo", "bar", "baz/asdf", "quux");
// 返回:\foo\bar\baz\asdf\quux
path.join(__dirname, "..", "views", "shop.html");
// __dirname: 当前文件夹的父目录
// '../': 上级目录
- 返回路径在不同的环境下可能有所不同;
- 如果有任何路径片段不是字符串,则抛出 TypeError。
dirname()
返回 path 的目录名,类似于 Unix dirname 命令。 尾随的目录分隔符被忽略。
path.dirname("/foo/bar/baz/asdf/quux");
// 返回: '/foo/bar/baz/asdf'
如果有任何路径片段不是字符串,则抛出 TypeError。
使用辅助函数来构建路径
util/path.js
const path = require("path"); // process.mainModule(require.main).filename 为我们提供了文件路径,该文件负责我们应用程序的运行,而这个文件名就是通过我们放在dirname里文件路径获取到的 module.exports = path.dirname(require.main.filename);const rootDir = require("../util/path"); res.sendFile(path.join(rootDir, "views", "shop.html"));这样我们就不需要编写根目录了。
os
帮助我们了解操作系统相关信息。
crypto
帮助我们将数据进行加密。
const crypto = require("crypto");
randomBytes()
生成随机字符,接收两个参数:
- 第一个参数:随机字符的数量
- 第二个参数:回调函数,内部传递一个出错时的 error 对象和存储字符的 buffer
crypto.randomBytes(32, (err, buffer) => {
if (err) {
console.log(err);
return res.redirect("/reset");
}
const token = buffer.toString("hex"); // 从缓冲区中生成一个token @1
});
@1:buffer 中存储字符是十六进制,需要通过
toString('hex')将十六进制的值转化为 ASCII。
例子
- 引入 http 模块,创建一个服务器监听 3000 端口;
- 在服务器中判断 3000 端口的路由地址:如果是根路由,则写入一段 HTML 代码(一个表单,里面含有输入框和提交按钮,表单的提交地址为
/message,提交方法为POST)后返回响应给浏览器;;
const http = require("http");
const fs = require("fs");
const server = http.createServer((req, res) => {
const url = req.url;
if (url === "/") {
// 如果url地址是/
res.write("<html>");
res.write("<head><title>Enter Message</title></head>");
res.write(
'<body><form action="/message method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>'
);
res.write("</html>");
return res.end(); // 返回退出代码,如果没有return则不会执行外层后面的res各个操作,就不能获取下面的Hello,Node.js页面
}
if (url === "/message" && method === "POST") {
const body = [];
// 监听data事件,当新的块(chunk)被读取时就会触发data事件,执行回调函数。函数接收一个参数块
req.on("data", (chunk) => {
body.push(chunk); // 将块推入到body中
});
req.on("end", () => {
const parseBody = Buffer.concat(body).toString(); // 创建一个缓冲区连接到body上
const message = parseBody.split("=")[1];
fs.writeFileSync("message.txt", message);
});
res.statusCode = 302;
res.setHeader("Location", "/");
// res.writeHead(302, {
// 'Location': '/'
// })
return res.end();
}
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>First page</title></head>");
res.write("<body><h1>Hello,Node.js</h1></body>");
res.write("</html>");
res.end();
});
server.listen(3000);
附录
res
响应对象可调用的常用方法:
setHeader:设置响应标头的单个属性,以键值对的方式修改,可调用多次;
res.setHeader("Location", "/"); // 设置地址跳转到/writeHead:设置响应头多个属性(包括状态码、状态信息和响应标头),只调用一次,可进行链式调用;
res.writeHead(statusCode, [reasonPhrase], [headers]); res.writeHead(200, { "Content-Type": "text/plain", Location: "/", });- statusCode:状态码;
reasonPhrase(可选):状态信息;
headers:响应标头;
注意:两个参数的最后一个参数是 headers 响应标头!三个参数只是方便 reasonPhrase。
注意:
setHeader和writeHead都有的时候,setHeader的内容合会并到writeHead,合并有冲突时以writeHead的内容为准(writeHead优先级高)。
req
请求数据的常用方法:
on:事件监听。接收两个参数,一个是监听的事件,一个是触发的函数:
// 监听data事件,当新的块(chunk)被读取时就会触发data事件,执行回调函数。函数接收一个默认参数,块(chunk) req.on("data", (chunk) => {}); // 在完成读取传入的数据或请求后结束监听 req.on("end", () => {});当遇到
req.on()时,Node.js 会自动在内部添加一个新的事件监听器来管理所有的监听器,相当于一个注册表在注册了这些事件但没有执行它,然后跳过继续执行下一条。(注册未来某个时间运行但不一定现在运行的代码函数)