网络操作
zKing 2018-12-08 Node.js
摘要
Node.js 提供了一个最为简单的 http 服务器的搭建,无需去配置 Apach,Nginx 等,只需要几行代码就可以启动一个服务器。
# http 和 https 模块
- http 模块支持服务端模式和客户端模式两种使用方式,当前支持 http1 协议
- HTTPS 是 HTTP 基于 TLS/SSL 的版本。在 Node.js 中,它被实现为一个独立的模块 https。
- 目前新出了一个 http2 模块,可以用于 http2 协议
这里以 http 模块的服务端模式做一个简单的例子,其实在做 Web 开发的时候也经常是用这种模式
const http = require("http");
//const https = require('https');
//调用 http 模块 的 API
const server = http.createServer(function(request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, { "Content-Type": "text/plain" });
// 发送响应数据 "Hello World"
response.end("Hello World!");
});
server.listen(8888, function() {
console.log("Server running at http://127.0.0.1:8888/");
});
// 以上程序创建了一个HTTP服务器并监听8888端口
// 打开浏览器访问该端口 http://127.0.0.1:8888/ 就能够看到效果。
- 创建服务的时候,可以使用
http.server
中的request
和response
两个对象参数 request
可以用来获取传送的数据和 http 头文件,response
则常用于对请求进行数据的响应- 它们除了可以用于读写头数据外,都可以当作数据流来操作。
# URL 处理
既然搭起了 http 服务器,那么怎么去进行路由管理?这就需要了解 url
模块,一般情况下,url.parse 方法加上 request.url 属性是处理 HTTP 请求时的固定搭配。
const http = require("http");
const { parse } = require("url");
const server = http.createServer(function(request, response) {
let pathName = parse(request.url).pathname;
response.writeHead(200, { "Content-Type": "text/plain" });
response.end(pathName);
});
server.listen(8888, function() {
console.log("Server running at http://127.0.0.1:8888/");
});
# 处理 GET/POST 请求
# 处理 GET 请求
处理 GET 请求相对容易些,只需要使用 url
模块即可。
const http = require("http");
const url = require("url");
http
.createServer(function(req, res) {
res.writeHead(200, {
"Content-Type": "application/json; charset=utf-8"
});
let query = url.parse(req.url, true).query;
res.end(JSON.stringify(query));
})
.listen(8888, function() {
console.log("Server running at http://127.0.0.1:8888/");
});
# 处理 POST 请求
处理 POST 请求稍微有些麻烦,需要使用 querystring
模块
const http = require("http");
const querystring = require("querystring");
var postHTML =
"<html><head></head>" +
"<body>" +
'<form method="post">' +
'网站名: <input name="name"><br>' +
'网站 URL: <input name="url"><br>' +
'<input type="submit">' +
"</form>" +
"</body></html>";
http
.createServer(function(req, res) {
var body = "";
req.on("data", function(chunk) {
body += chunk;
});
req.on("end", function() {
// 解析参数
body = querystring.parse(body);
// 设置响应头部信息及编码
res.writeHead(200, {
"Content-Type": "text/html; charset=utf8"
});
if (body.name && body.url) {
// 输出提交的数据
res.write("网站名:" + body.name);
res.write("<br>");
res.write("网站 URL:" + body.url);
} else {
res.write(postHTML); // 输出表单
}
res.end();
});
})
.listen(8888, function() {
console.log("Server running at http://127.0.0.1:8888/");
});
# 压缩文件
使用 zlib 模块可以减少使用 HTTP 协议时的数据传输量。
var fs = require("fs");
var zlib = require("zlib");
fs.createReadStream("input.txt") // 需要压缩的数据
.pipe(zlib.createGzip()) // 压缩的方式
.pipe(fs.createWriteStream("input.txt.gz")); // 输出的位置
console.log("文件压缩完成。");
以上是个简单的 zlib 示例,在用于 http 传输的时候,还需要返回一个 http 头信息'Content-Encoding': 'gzip'
,将输出的位置改成 response
对象。
fs.createReadStream("input.txt")
.pipe(zlib.createGzip())
.pipe(response);
# net 模块
net 模块是同样是 Node.js 的核心模块。在 http 模块概览里提到,http.Server 继承了 net.Server,此外,http 客户端与 http 服务端的通信均依赖于 socket(net.Socket)。也就是说,做 node 服务端编程,net 基本是绕不开的一个模块。
从组成来看,net 模块主要包含两部分
- net.Server:TCP server,内部通过 socket 来实现与客户端的通信。
- net.Socket:tcp/本地 socket 的 node 版实现,它实现了全双工的 stream 接口。
# 简单示例
server.js
var net = require("net");
var PORT = 3000;
var HOST = "127.0.0.1";
var server = net.createServer(function(socket) {
console.log("服务端:收到来自客户端的请求");
socket.on("data", function(data) {
console.log("服务端:收到客户端数据,内容为{" + data + "}");
// 给客户端返回数据
socket.write("你好,我是服务端");
});
socket.on("close", function() {
console.log("服务端:客户端连接断开");
});
});
server.listen(PORT, HOST, function() {
console.log("服务端:开始监听来自客户端的请求");
});
client.js
var net = require("net");
var PORT = 3000;
var HOST = "127.0.0.1";
var client = net.createConnection(PORT, HOST);
client.on("connect", function() {
console.log("客户端:已经与服务端建立连接");
});
client.on("data", function(data) {
console.log("客户端:收到服务端数据,内容为{" + data + "}");
});
client.on("close", function(data) {
console.log("客户端:连接断开");
});
client.end("你好,我是客户端");
先启动 server.js 再启动 client.js,即可看到示例
# 总结
再进行Web 开发的时候,主要是使用 http 模块,然后通过 url 和 querystring 模块来进行数据传输。 zlib 模块则常用于文件压缩做性能优化,net 模块则是用于底层较多,不过多介绍。