Node.js 从入门到进阶
什么是 NodeJs?
Nodejs 是一个 JavaScript 运行时环境。那么,JavaScript 运行时究竟是什么呢?你可能对 JavaScript 这个术语很熟悉。JavaScript 是一种编程语言,你可以用它来控制浏览器中的 DOM,并帮助处理浏览器中加载的页面。它是一种基于浏览器的脚本语言,允许你在页面加载后与页面进行交互,这使其成为在浏览器中开发交互式用户界面的关键组件。然而,JavaScript 还有其他令人兴奋的用途。Nodejs 是 JavaScript 的修改版本,并添加了新功能。
简而言之,Node.js 将 JavaScript 置于一个全新的环境中。你可能会说,这允许你在服务器上运行 JavaScript 代码,但理论上它可以在任何系统上运行。因此,你可以在浏览器之外的地方使用 JavaScript,就像它是另一种标准编程语言一样。因此,Node.js 是创建服务器端 Web 应用的绝佳解决方案。服务器本质上就是连接到互联网并在世界任何地方运行的计算机。
所以,我们可以利用 Node.js 在浏览器之外运行 JavaScript,这太棒了!Nodejs 使用了 Google 的 JavaScript 引擎 V8。V8 将您的 JavaScript 代码编译为机器码。V8 是用 C++ 编写的,但是,您无需编写任何 C++ 代码即可使用 JavaScript 或 Node.js。因此,Node.js 采用了用 C++ 编写的 V8 代码库,并添加了处理本地文件系统、打开文件、读取文件和删除文件等功能,所有这些功能在浏览器中都不可用。由于安全问题,您无法在浏览器中访问本地文件系统,因此,如果您之后安装 Node.js,您将能够使用扩展的 V8 版本。简而言之,Nodejs 允许您在计算机上运行 JavaScript,并为 JavaScript 引擎添加了有用的功能,使您能够做更多疯狂和奇妙的事情。
创建一个简单的第一个演示应用程序。
const fs = require(‘fs’)
fs.writeFileSync(“Hello.txt”,”Hello There”)
现在我们对 Nodejs 是什么以及如何使用它有了基本的了解。在服务器上运行 Node.js 来编写服务器端代码。
这时服务器就派上用场了。有了服务器、计算机和 IP 地址,就可以在服务器上运行一些代码,处理传入的请求并提供响应,也就是浏览器可以显示的 HTML 页面。
顺便说一句,它并不总是简单的 HTML;它还可能包含 CSS 文件或 JavaScript 文件,这些文件包含浏览器而非服务器的 JavaScript 代码。我们现在在服务器上执行一些由于性能或安全原因在浏览器上无法执行的操作。
-
为了获取和保存数据,我们链接到数据库。
-
我们执行用户身份验证以使其更加安全,但我们只能在用户无法访问的位置执行此操作。
-
我们利用它进行输入验证,以确定用户是否输入了正确的电子邮件地址,并且我们的业务逻辑存储在服务器上。由于浏览器加载时间过长,用户不应该查看所有内容。
我们当然希望提供快速的用户体验,因此我们使用了 Node.js 和 JavaScript 代码,但这次不是在浏览器上,而是在服务器上。我们通过服务器实现 Node.js 提供的功能,并通过请求-响应模式间接地允许用户与服务器交互。因此,在本课程中,我们将以同样的方式使用 Node.js:我们将使用它来开发服务器端代码,生成用户和客户端可以使用的数据。值得注意的是,Node.js 不仅仅是用于在服务器上运行代码;它也是一个 JavaScript 运行时,正如您所见,它本身不需要使用浏览器。
Node.js 也经常用于其他编程,例如本地实用程序脚本或构建工具。假设你想尝试 React、Angular、Vue 或任何类似的框架。在这种情况下,你将在这些语言或框架所需的所有构建过程中间接地使用 Node.js,因为 Node.js 是一个非常棒的实用程序脚本开发工具。Node.js 的一个显著优势,或者至少是一个显著的优势,在于它使用 JavaScript。JavaScript 在当今的 Web 开发中被广泛用于所有前端和构建工具,如果你能在服务器端使用它,你就不需要学习很多不同的语言了。
你可以通过两种方式编写 Node 代码。一种方法是创建可执行文件,另一种是使用 REPL。如果你直接在终端中输入 node,那么你现在就进入了 REPL,这可以通过在开头不再包含计算机名称的完整路径来判断。你可以使用 Node 命令,例如 console log、two plus two,或者从 REPL 中写入和操作文件。这些代码行并非独立存在,使用 REPL 的缺点是关闭后会丢失所有代码。所以,我们使用可执行文件,以便以后保存它们。
网络如何运作?
假设您正坐在电脑前,正在访问一个网页,并引发互动。假设您正在访问浏览器并输入一个网址。后台发生的事情是,浏览器会联系一些域名服务器来查找该域名,因为这个域名实际上并非您服务器的地址,而只是该地址的编码版本,方便用户阅读。您的服务器已分配一个 IP 地址。因此,您或您的浏览器会向该 IP 地址的服务器发送请求。
终于,我们到了 Node.js 真正发挥作用的时刻,你的 Node.js 代码至关重要。你需要编写在特定 IP 地址的互联网计算机上运行的代码,并启动服务器来处理传入的请求并执行相应的操作。在这段代码中,你可以执行诸如验证用户输入、与数据库通信(数据库可能在不同的数据库服务器上运行,但你通常会从后端访问它)以及向客户端返回响应等操作。
响应可以是客户端需要处理的 HTML 文本或 HTML 代码,也可以是其他类型的数据,例如文件、JSON 或 XML 数据。这里的响应不仅仅是内容,记住,响应和请求都有标头,这就是 Web 的一般工作原理。请求和响应的传输是通过协议完成的,HTTP 和 HTTPS 就是其中的代表。
-
HTTP(超文本传输协议):浏览器和服务器都能理解的传输数据的协议。
-
HTTPS(安全超文本传输协议):一种浏览器和服务器能够理解的安全数据传输协议。
创建自己的服务器:
const http = require("http");
const server = http.createServer((req, res) => {
console.log(req);
});
server.listen(3000);
我们将为这个项目创建自己的服务器。为此,我们将使用 HTTP 提供的 createServer 方法。
Node JS 程序生命周期。
我们使用 node app.js 来运行该文件,因为它的名字是 app.js。这实际上启动了脚本,Node.js 在其中遍历整个文件,解析代码,注册变量和函数等等,实际上是读取并执行了我们的全部代码。但奇怪的是:我们从未离开过那个程序。原因在于 Node.js 中一个叫做事件循环的关键概念。它是一个由 Node.js 管理的循环进程,只要有工作要做或有注册的事件监听器,它就会持续运行。
我们传递了一个函数来构造一个服务器,它本质上是一个持续的事件监听器,我们没有注销它,而且我们也不应该注销,因为我们的服务器应该始终处于活动状态。所以这个事件循环负责我们的主要 Node 应用程序。Node.js 采用事件驱动的方法处理各种任务,而不仅仅是服务器管理。整个 Node 进程在我们 PC 上的单个线程上运行。
现在,正如你所料,如果我们用 Node.js 构建一个服务器,它应该能够处理数百万个传入请求。如果它必须暂停,然后不断地对每个请求执行某些操作,那效率会很低,所以它使用了事件循环的概念,它会持续运行,并且只在特定事件发生时执行代码,以确保它始终可用。虽然这看起来似乎没问题,但如果有两个传入请求,它就必须处理两个事件,而且它处理这些请求的速度确实非常快。它利用操作系统的功能在后台进行了一些多线程处理。
退出事件循环
const http = require("http");
const server = http.createServer((req, res) => {
console.log(req);
process.exit();
});
server.listen(3000);
process.exit() 只是取消注册/结束/退出整个过程
代码部分
理解请求
const http = require("http");
const server = http.createServer((req, res) => {
console.log(req.url, req.method, req.headers);
// process.exit();
});
server.listen(3000)
发送响应
const http = require("http");
const server = http.createServer((req, res) => {
console.log(req.url, req.method, req.headers);
// process.exit();
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>My First Page</title></head>");
res.write("<body><h1>Hello From Node.js Server!</h1></body>");
res.write("</html>");
res.end();
});
server.listen(3000);
路由请求
const http = require("http");
const server = http.createServer((req, res) => {
const url = req.url;
if (url === "/") {
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>Server</title></head>");
res.write(
'<body><form action="/message" method="POST"><input type="text" value=""></form></body>'
);
res.write("</html>");
return res.end();
} else if (url === "/secondserver") {
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>Server Page second</title></head>");
res.write("<body><h2>Welcome to the Internet</h2></body>");
res.write("</html>");
res.end();
}
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>Server Page second</title></head>");
res.write("<body><h2>Welcome to the Internet</h2></body>");
res.write("</html>");
res.end();
});
server.listen(3000);
重定向请求
const http = require("http");
const fs = require("fs");
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
if (url === "/") {
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>Server</title></head>");
res.write(
'<body><form action="/message" method="POST"><input type="text" value=""></form></body>'
);
res.write("</html>");
return res.end();
}
if (url === "/message" && method === "POST") {
fs.writeFileSync("testing.txt", "YOLO WORLD");
res.statusCode = 302;
res.setHeader("Location", "/");
return res.end();
}
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>Server Page second</title></head>");
res.write("<body><h2>Welcome to the Internet</h2></body>");
res.write("</html>");
res.end();
});
server.listen(3000);
解析请求主体
const http = require("http");
const fs = require("fs");
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
if (url === "/") {
res.write("<html>");
res.write("<head><title>Server</title></head>");
res.write(
'<body><form action="/message" method="POST"><input type="text" name="message" value=""></form></body>'
);
res.write("</html>");
return res.end();
}
if (url === "/message" && method === "POST") {
const body = [];
req.on("data", (chunk) => {
console.log(chunk);
body.push(chunk);
});
req.on("end", () => {
const parseBody = Buffer.concat(body).toString();
const message = parseBody.split("=")[1];
fs.writeFileSync("testing.txt", message);
});
res.statusCode = 302;
res.setHeader("Location", "/");
return res.end();
}
res.setHeader("Content-Type", "text/html");
res.write("<html>");
res.write("<head><title>Server Page second</title></head>");
res.write("<body><h2>Welcome to the Internet</h2></body>");
res.write("</html>");
res.end();
});
server.listen(3000);
流和缓冲区:
Node 中使用流来处理流数据,例如视频、大文件等。Node.js 中的所有流都通过 streams 模块进行管理。
Node 中有四种不同类型的流:
-
可读流:要生成可读取的数据流,请使用可读流。
-
可写流:用于生成可写入的数据流。
-
双工流:要构建一个同时可读可写的流,请使用双工流。双工流可以读取和写入(例如,客户端和服务器之间的套接字连接)。
-
转换流:创建可读可写流,并能够在读取和写入数据时修改数据。
缓冲区
流基于缓冲的概念。缓冲区是流用来存储数据的一块临时内存,直到被使用为止。
全文 => https://aviyel.com/post/1149
如果您是项目维护者、贡献者或只是开源爱好者,请关注@aviyelHQ或在 Aviyel 上注册以获得早期访问权限。
加入 Aviyel 的 Discord => Aviyel 的世界
推特 => https://twitter.com/AviyelHq
官方网站 => https://aviyel.com
文章来源:https://dev.to/pramit_marattha/node-js-from-beginners-to-advance-31id