Node.js入门之http模块和dns模块

简介: 在nodejs中,http可以说是最核心的模块,借助http模块,可以几行代码就搞定一个超迷你的web server。学好http模块对于后面的web框架express、koa的学习也很有帮助。

http服务分为客户端和服务端。我们先来说说服务端。

服务端

创建HTTP服务器

http.createServer(fn)用来创建http服务器

const http = require("http");

const server = http.createServer((serverReq, serverRes) => {});

当服务器收到客户端的请求后就会进入该方法serverReq是请求对象,serverRes是服务器端响应对象。

启动HTTP服务器

server.listen(port,[host],[backlog],[callback]);用来启动服务器。

  • port 监听的端口号
  • host 监听的地址
  • backlog 指定位于等待队列中的客户端连接数
  • callback 回调函数
server.listen(3000, () => {
  console.log("服务启动啦")
})

关闭HTTP服务器

server.close()用来关闭http服务,并且还可以监听该事件。

const http = require("http");

const server = http.createServer(function (serverReq, serverRes) {
  const url = serverReq.url;
  serverRes.end("您访问的地址是:" + url);
});

server.on("close", () => {
  console.log("服务关闭啦");
});

server.listen(3000, () => {
  console.log("服务器端开始监听!");
  server.close();
});

监听服务器错误

server.on('error', (e)=>{
  console.log(e)
});

设置超时时间

通过server.setTimeout(msecs, callback)设置超时时间,超时后不可再复用已经建立的连接,需要发请求需要重新建立连接。默认超时时间是2分钟。

server.setTimeout(msecs, callback);

通过监听timeout事件来进行超时处理。

server.on('timeout',function(){
  console.log('连接已经超时');
});

服务端请求对象

服务端请求对象req它其实是http.IncomingMessage实例,我们通常会用它来获取headerurl
、参数等信息。

获取请求链接、http版本、请求方法、请求头部

const http = require("http");

const server = http.createServer((req, res) => {
  console.log("1、客户端请求url:" + req.url);
  console.log("2、http版本:" + req.httpVersion);
  console.log("3、http请求方法:" + req.method);
  // 这里使用JSON.stringify是为了方便在控制台查看,实际上是一个对象可以直接使用
  console.log("4、http请求头部" + JSON.stringify(req.headers));

  res.write("hello");
  res.end("world");
});

我们在浏览器键入http://localhost:3000/hello输出如下

image.png

获取get请求参数

既然有请求,那一定会有参数,我们先来说说获取get请求参数。

get请求的参数都会在url里面,我们一般会使用前面学习的url或者querystring模块进行处理。

const http = require("http");
const url = require("url");

const server = http.createServer((req, res) => {
  // 利用前面学习的url模块进行参数处理
  const params = url.parse(req.url, true);
  console.log(params.query);

  res.write("hello");
  res.end("world");
});

我们在浏览器键入http://localhost:3000/hello?name=randy输出如下

image.png

获取post请求参数

我们知道,get请求的参数是在浏览器路径里面,但是post请求的参数是在请求体里面,那这样我们怎么获取到参数呢?

这里就要用到请求对象req的一些事件了。

const http = require("http");

const server = http.createServer((req, res) => {
  let body = "";
  req.on("data", function (thunk) {
    body += thunk;
  });

  req.on("end", function () {
    console.log("post body is: " + body);
    res.end("ok");
  });
});

我们用postman构造一个post请求,http://localhost:3000传递参数name:jack输出如下

image.png

服务端响应对象

服务端响应对象,它其实是http.ServerResponse实例。

当接受到来自客户端的http请求后,用来向客户端返回响应内容,比如状态代码/状态描述信息、响应头部、响应主体。

设置状态代码、状态描述信息

我们可以通过res.statusCoderes.statusMessage来设置状态代码、状态描述信息。

当然你也可以直接使用设置头部方法res.writeHead来设置。相当于是一个简写。

const server = http.createServer((req, res) => {
  
  // 简写 res.writeHead(200, "ok")
  
  res.statusCode = 200;
  res.statusMessage = "ok";
  
  res.write("hello");
  res.end("world");
});

设置响应头

我们使用res.writeHead()res.setHeader() 来实现响应头部的设置。

不过需要注意,就是setHeader只能写在writeHead的前面,不然会报错。也就是说writeHead可以覆盖setHeader,但是反过来不行。

const http = require("http");
const url = require("url");

const server = http.createServer((req, res) => {
  // 设置头部,只能在writeHead的前面,不能在后面。但是writeHead可以覆盖setHeader
  res.setHeader("Content-Type", "text-plain");

  res.writeHead(200, "ok", {
    "Content-Type": "text/html",
  });
  
  res.write("hello");
  res.end("world");
});

获取响应头、删除响应头

既然可以设置响应头,当然也可以获取和删除响应头。通过getHeaderremoveHeader来获取和删除响应头。

const http = require("http");
const url = require("url");

const server = http.createServer((req, res) => {

  // 设置
  res.setHeader("Content-Type", "text-plain");
  // 获取
  console.log(res.getHeader("content-type")); //text-plain
  // 删除
  res.removeHeader("Content-Type");
  
  res.writeHead(200, "ok", {
    "Content-Type": "text/plain",
  });

  res.write("hello");
  res.end("world");
});

设置响应主体

设置响应主体主要用到 res.write() 以及 res.end() 两个方法

response.write(chunk[, encoding][, callback])

  • chunk:响应主体的内容,可以是string,也可以是buffer。当为string时,encoding参数用来指明编码方式。(默认是utf8)
  • encoding:编码方式,默认是 utf8。
  • callback:当响应体flushed时触发。

response.end([data][, encoding][, callback])

掌握了 res.write() 的话,res.end() 就很简单了。res.end() 的用处是告诉nodejs,header、body都给你了,这次响应就到这里吧。简单理解就是传递响应体并结束。

客户端

http服务除了用在服务端,还可以用在客户端。对于客户端主要用来创建http客户端请求。

创建GET请求

下面构造了个GET请求,访问 http://jsonplaceholder.typicode.com/todos/1 ,并将返回的内容打印在控制台。

const http = require("http");

const options = {
  protocol: "http:",
  hostname: "jsonplaceholder.typicode.com/todos/1",
  port: "80",
  path: "/",
  method: "GET",
};

const client = http.request(options, function (req) {
  let data = "";
  req.setEncoding("utf8");
  req.on("data", function (chunk) {
    data += chunk;
  });
  req.on("end", function () {
    console.log(data);
  });
  
  console.log(req.statusCode); // 200
  console.log(req.statusMessage); // ok
});

client.end();

输出如下,可以看到,通过get请求,获取到了返回的内容。

image.png

当然,我们还可以用便捷方法 http.get(options)

http.get("http://jsonplaceholder.typicode.com/todos/1", function (req) {
  let data = "";
  req.setEncoding("utf8");
  req.on("data", function (chunk) {
    data += chunk;
  });
  req.on("end", function () {
    console.log(data);
  });
  
  console.log(req.statusCode); // 200
  console.log(req.statusMessage); // ok
});

创建post请求

下面构造了个POST请求,访问 http://jsonplaceholder.typicode.com/posts ,并将返回的内容打印在控制台。

const options = {
  method: "POST",
  protocol: "http:",
  hostname: "jsonplaceholder.typicode.com",
  port: "80",
  path: "/posts",
  headers: {
    connection: "keep-alive",
    "content-type": "application/json; charset=UTF-8",
  },
};

// 发送给服务端的数据
const postBody = {
  title: "foo",
  body: "bar",
  userId: 1,
};

// 创建客户端请求
const client = http.request(options, function (req) {
  let data = "";
  req.on("data", function (chunk) {
    data += chunk;
  });
  req.on("end", function () {
    console.log(data);
  });
  
  console.log(req.statusCode); // 200
  console.log(req.statusMessage); // ok
});

client.write(JSON.stringify(postBody));
client.end();

输出如下,可以看到,通过post请求,获取到了返回的内容。

image.png

可以发现,服务端、客户端都有req对象,它们其实都是http.IncomingMessage实例。那这两者是一样的吗?其实是有细微差别的。具体如下图

image.png

取消请求

可以使用abort方法来终止本次请求

req.abort();

域名解析

域名解析顾名思义,就是将于域名解析为ip地址。在node中我们可以使用dns模块来实现该功能。

下面我们来说说dns模块两个个常用的方法lookupresolve4

lookup()

比如我们要查询域名 www.qq.com 对应的ip,可以通过 dns.lookup()

const dns = require("dns");

dns.lookup("www.qq.com", function (err, address, family) {
  if (err) throw err;
  console.log("ip地址为: " + address); // 101.91.22.57
});

我们知道,同一个域名,可能对应多个不同的ip。那么,如何获取一个域名对应的多个ip呢?可以这样。

const dns = require('dns');
const options = { all: true };

dns.lookup("www.qq.com", options, function (err, address, family) {
  if (err) throw err;

  console.log("ip地址为: " + JSON.stringify(address)); // [{"address":"101.91.22.57","family":4},{"address":"101.91.42.232","family":4}]
});

resolve4()

上面的例子,我们使用resolve4方法也能实现。

dns.resolve4("www.qq.com", function (err, address) {
  if (err) throw err;
  console.log(JSON.stringify(address)); // ["101.91.22.57","101.91.42.232"]
});

从上面的例子来看,两个方法都可以查询域名的ip列表。那么,它们的区别在什么地方呢?

可能最大的差异就在于,当配置了本地Host时,是否会对查询结果产生影响。

  • dns.lookup():有影响。
  • dns.resolve4():没有影响。

举例,在hosts文件里配置了如下规则。

127.0.0.1 www.qq.com

运行如下对比示例子,就可以看到区别。

const dns = require('dns');

dns.lookup('www.qq.com', function(err, address, family){
    if(err) throw err;
    console.log('配置host后,dns.lokup =>' + address);
});

dns.resolve4('www.qq.com', function(err, address, family){
    if(err) throw err;
    console.log('配置host后,dns.resolve4 =>' + address);
});

输出如下

配置host后,dns.lookup =>127.0.0.1
配置host后,dns.resolve4 =>182.254.34.74

系列文章

Node.js入门之什么是Node.js

Node.js入门之path模块

Node.js入门之fs模块

Node.js入门之url模块和querystring模块

Node.js入门之http模块和dns模块

Node.js入门之process模块、child_process模块、cluster模块

听说你还不会使用Express?

听说你还不会使用Koa?

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!

相关文章
|
7月前
|
JavaScript 前端开发
在Node.js中,如何合理使用模块来避免全局变量的问题?
在Node.js中,如何合理使用模块来避免全局变量的问题?
299 71
|
6月前
|
JavaScript 前端开发 API
Node.js中发起HTTP请求的五种方式
以上五种方式,尽管只是冰山一角,但已经足以让编写Node.js HTTP请求的你,在连接世界的舞台上演奏出华丽的乐章。从原生的 `http`到现代的 `fetch`,每种方式都有独特的风格和表现力,让你的代码随着项目的节奏自由地舞动。
682 65
|
7月前
|
JavaScript 前端开发 开发者
Node学习笔记:HTTP模块
总的来说,Node.js的HTTP模块是一个强大的工具,可以帮助你处理HTTP协议的各种需求。无论你是想开设自己的餐厅(创建服务器),还是想去别的餐厅点菜(发出请求),HTTP模块都能满足你的需求。
272 18
|
9月前
|
JSON JavaScript 前端开发
菜鸟之路Day23一一JavaScript 入门
本文介绍了 JavaScript 的基础内容,包括 JS 的引入方式、基础语法、数据类型、运算符、类型转换、函数、对象(如 Array、String、自定义对象、JSON、BOM 和 DOM)、事件监听,以及 Vue 框架的初步使用。重点讲解了内部和外部脚本的引入、变量声明(var、let、const)、常见输出语句、数组与字符串的操作方法、DOM 操作及事件绑定,并通过实例展示了 Vue 的双向数据绑定和常用指令(v-bind、v-model、v-on、v-if、v-for 等)。
247 7
|
JavaScript 前端开发
【JavaScript】——JS基础入门常见操作(大量举例)
JS引入方式,JS基础语法,JS增删查改,JS函数,JS对象
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
1816 1
|
9月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
933 29
|
9月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
399 4
|
9月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
9月前
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。

相关产品

  • 云解析DNS