首页 > 编程语言 >node-http模块:服务器与客户端

node-http模块:服务器与客户端

时间:2024-09-24 10:50:48浏览次数:1  
标签:node HTTP 请求 res byvoid http data 客户端

HTTP 服务器与客户端

Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP客户端。 http.Server 是一个基于事件的 HTTP服务器,它的核心由 Node.js 下层 C++部分实现,而接口由 JavaScript 封装,兼顾了高性能与简易性。 http.request 则是一个HTTP 客户端工具,用于向 HTTP 服务器发起请求。

HTTP 服务器

http.Server 是 http 模块中的 HTTP 服务器对象,用 Node.js 做的所有基于 HTTP 协议的系统,如网站、社交应用甚至代理服务器,都是基于 http.Server 实现的。它提供了一套封装级别很低的 API,仅仅是流控制和简单的消息解析,所有的高层功能都要通过它的接口来实现。

//app.js
var http = require('http');
http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.write('<h1>Node.js</h1>');
  res.end('<p>Hello World</p>');
}).listen(3000);

console.log("HTTP server is listening at port 3000.");

这段代码中, http.createServer 创建了一个 http.Server 的实例,将一个函数作为 HTTP 请求处理函数

这个函数接受两个参数,分别是请求对象( req )和响应对象( res )

在函数体内, res 显式地写回了响应代码 200 (表示请求成功),指定响应头为'Content-Type': 'text/html',然后写入响应体 '<h1>Node.js</h1>',通过 res.end结束并发送。最后该实例还调用了 listen 函数,启动服务器并监听 3000 端口。

http.Server 的事件

http.Server 是一个基于事件的 HTTP 服务器,所有的请求都被封装为独立的事件,开发者只需要对它的事件编写响应函数即可实现 HTTP 服务器的所有功能。它继承自EventEmitter,提供了以下几个事件。

  • request:当客户端请求到来时,该事件被触发,提供两个参数 req 和res,分别是http.ServerRequesthttp.ServerResponse 的实例,表示请求和响应信息。
  • connection:当 TCP 连接建立时,该事件被触发,提供一个参数 socket,为net.Socket 的实例connection 事件的粒度要大于 request,因为客户端在Keep-Alive 模式下可能会在同一个连接内发送多次请求。
  • close :当服务器关闭时,该事件被触发。注意不是在用户连接断开时。

除此之外还有 checkContinue、 upgrade、 clientError 事件,通常我们不需要关心,只有在实现复杂的 HTTP 服务器的时候才会用到。

在这些事件中 , 最 常 用 的 就 是 request 了 , 因 此 http 提 供 了 一 个 捷 径 :http.createServer([requestListener]) , 功 能 是 创 建 一 个 HTTP 服 务 器 并 将requestListener 作为 request 事件的监听函数,这也是我们前面例子中使用的方法。事实上它显式的实现方法是:

//httpserver.js
var http = require('http')
var server = new http.Server()
server.on('request', function (req, res) {
  res.writeHead(200, { 'Content-Type': 'text/html' })
  res.write('<h1>Node.js</h1>')
  res.end('<p>Hello World</p>')
})
server.listen(3000)

console.log('HTTP server is listening at port 3000.')

http.ServerRequest

http.ServerRequest 是 HTTP 请求的信息,是后端开发者最关注的内容。它一般由http.Server 的 request 事件发送,作为第一个参数传递,通常简称 request 或 req。ServerRequest 提供一些属性,如下。

名称 含义
complete 客户端请求是否已经发送完成
httpVersion HTTP 协议版本,通常是 1.0 或 1.1
method HTTP 请求方法,如 GET、 POST、 PUT、 DELETE 等
url 原始的请求路径,例如 /static/image/x.jpg 或 /user?name=byvoid
headers HTTP 请求头
trailers HTTP 请求尾(不常见)
connection 当前 HTTP 连接套接字,为 net.Socket 的实例
socket connection 属性的别名
client client 属性的别名

http.ServerResponse

http.ServerResponse 是返回给客户端的信息,决定了用户最终能看到的结果。它也是由 http.Server 的 request 事件发送的,作为第二个参数传递,一般简称为response 或 res

http.ServerResponse 有三个重要的成员函数,用于返回响应头响应内容以及结束请求

  • response.writeHead(statusCode, [headers]):向请求的客户端发送响应头。statusCode 是 HTTP 状态码,如 200 (请求成功)、 404 (未找到)等。 headers是一个类似关联数组的对象,表示响应头的每个属性。该函数在一个请求内最多只能调用一次,如果不调用,则会自动生成一个响应头。
  • response.write(data, [encoding]):向请求的客户端发送响应内容data 是一个 Buffer 或字符串,表示要发送的内容。如果 data 是字符串,那么需要指定encoding 来说明它的编码方式,默认是 utf-8在 response.end 调用之前,response.write 可以被多次调用。
  • response.end([data], [encoding]):结束响应,告知客户端所有发送已经完成当所有要返回的内容发送完毕的时候,该函数 必须 被调用一次。它接受两个可选参数,意义和 response.write 相同。如果不调用该函数,客户端将永远处于等待状态。

获取 GET 请求内容

注意, http.ServerRequest 提供的属性中没有类似于 PHP 语言中的 $_GET 或$_POST 的属性,那我们如何接受客户端的表单请求呢?

由于 GET 请求直接被嵌入在路径中, URL是完整的请求路径,包括了 ? 后面的部分,因此你可以手动解析后面的内容作为 GET请求的参数。 Node.js 的 url 模块中的 parse 函数提供了这个功能,

var http = require('http')
var url = require('url')
var util = require('util')
http
  .createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' })
    res.end(util.inspect(url.parse(req.url, true)))
  })
  .listen(3000)

浏览器返回的结果:

{
  search: '?name=byvoid&[email protected]',
  query: { name: 'byvoid', email: '[email protected]' },
  pathname: '/user',
  path: '/user?name=byvoid&[email protected]',
  href: '/user?name=byvoid&[email protected]'
}

通过 url.parse,原始的 path 被解析为一个对象,其中 query 就是我们所谓的 GET请求的内容,而路径则是 pathname。

获取 POST 请求内容

相比GET 请求把所有的内容编码到访问路径中, POST 请求的内容全部都在请求体中

http.ServerRequest 并没有一个属性内容为请求体,原因是等待请求体传输可能是一件耗时的工作,譬如上传文件。而很多时候我们可能并不需要理会请求体的内容,恶意的 POST请求会大大消耗服务器的资源。所以 Node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做

var http = require('http')
var querystring = require('querystring')
var util = require('util')

http.createServer(function (req, res) {
    var post = ''
    req.on('data', function (chunk) {
      post += chunk
    })
    req.on('end', function () {
      post = querystring.parse(post)
      res.end(util.inspect(post))
    })
  })
  .listen(3000)

通过req的data事件监听函数,每当接受到请求体的数据,就累加到 post 变量中在end事件触发后,通过 querystring.parse 将post解析为真正的POST请求格式

HTTP 客户端

http 模块提供了两个函数 http.request 和 http.get,功能是作为客户端向 HTTP服务器发起请求。

http.request(options, callback)发起 HTTP请求。接受两个参数, option 是一个类似关联数组的对象,表示请求的参数, callback 是请求的回调函数。 option常用的参数如下所示。

  • host :请求网站的域名或 IP 地址。
  • port :请求网站的端口,默认 80。
  • method :请求方法,默认是 GET。
  • path :请求的相对于根的路径,默认是“/”。 QueryString 应该包含在其中。例如 /search?query=byvoid。
  • headers :一个关联数组对象,为请求头的内容。

callback 传递一个参数,为 http.ClientResponse 的实例。

http.request 返回一个 http.ClientRequest 的实例

//httprequest.js
var http = require('http')
var querystring = require('querystring')
var contents = querystring.stringify({
  name: 'byvoid',
  email: '[email protected]',
  address: 'Zijing 2#, Tsinghua University',
})
var options = {
  host: 'www.byvoid.com',
  path: '/application/node/post.php',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': contents.length,
  },
}
var req = http.request(options, function (res) {
  res.setEncoding('utf8')
  res.on('data', function (data) {
    console.log(data)
  })
})
req.write(contents)
req.end()

不要忘了通过 req.end() 结束请求,否则服务器将不会收到信息

http.get(options, callback) http 模块还提供了一个更加简便的方法用于处理GET请求: http.get。它是 http.request 的简化版,唯一的区别在于http.get自动将请求方法设为了 GET 请求,同时不需要手动调用 req.end()。

var http = require('http')
http.get({ host: 'www.byvoid.com' }, function (res) {
  res.setEncoding('utf8')
  res.on('data', function (data) {
    console.log(data)
  })
})

http.ClientRequest

http.ClientRequest 是由 http.request 或 http.get 返回产生的对象,表示一个已经产生而且正在进行中的 HTTP请求

它提供一个 response 事件,即 http.request或 http.get 第二个参数指定的回调函数的绑定对象。我们也可以显式地绑定这个事件的监听函数:

//httpresponse.js
var http = require('http')
var req = http.get({ host: 'www.byvoid.com' })
req.on('response', function (res) {
  res.setEncoding('utf8')
  res.on('data', function (data) {
    console.log(data)
  })
})

http.ClientRequest 像 http.ServerResponse 一样也提供了 write 和 end 函数,用于向服务器发送请求体,通常用于 POST、 PUT 等操作。

所有写结束以后必须调用 end函数以通知服务器,否则请求无效。 http.ClientRequest 还提供了以下函数。

  • request.abort():终止正在发送的请求。
  • request.setTimeout(timeout, [callback]):设置请求超时时间, timeout 为毫秒数。当请求超时以后, callback 将会被调用。

http.ClientResponse

http.ClientResponse 与 http.ServerRequest 相似,提供了三个事件 data、 end和 close,分别在数据到达、传输结束和连接结束时触发,其中 data 事件传递一个参数chunk,表示接收到的数据

http.ClientResponse 也提供了一些属性,用于表示请求的结果状态。

名称 含义
statusCode HTTP 状态码,如 200、 404、 500
httpVersion HTTP 协议版本,通常是 1.0 或 1.1
headers HTTP 请求头
trailers HTTP 请求尾(不常见)

http.ClientResponse 还提供了以下几个特殊的函数。

  • response.setEncoding([encoding]):设置默认的编码,当 data 事件被触发时,数据将会以 encoding 编码。默认值是 null,即不编码,以 Buffer 的形式存储。常用编码为 utf8。
  • response.pause():暂停接收数据和发送事件,方便实现下载功能。
  • response.resume():从暂停的状态中恢复。

标签:node,HTTP,请求,res,byvoid,http,data,客户端
From: https://www.cnblogs.com/niehao/p/18428684

相关文章

  • nodejs-get和post接收前端传递过来的参数
    一、接收GET请求参数在Node.js中,处理GET请求时,参数通常会附加在URL的查询字符串中。你可以使用url模块或express框架来解析这些参数。1、使用url模块consthttp=require('http');consturl=require('url');http.createServer((req,res)=>{constqueryObject=url.......
  • POST请求:掌握HTTP协议的强大功能
    在网络编程和API交互中,HTTP协议扮演着至关重要的角色。POST请求,作为HTTP协议中的一个核心方法,广泛应用于数据提交、用户登录、表单处理等场景。本文将详细介绍POST请求的基本概念、使用场景以及如何在不同编程语言中实现POST请求。什么是POST请求?POST(PostMethod)是一种HTTP方法,......
  • nodejs child_process 操作git 提交记录 提取git commit信息
    /***记录发布时的commit信息,用于区分内网版本包之间的差异*/importpathfrom'path';import{writeFileSync}from'fs';import{execSync}from'child_process';letoutputFileName=process.argv[2];if(!outputFileName){outputFileNam......
  • 如何使用 Bittly 为基于 HTTP 的 API 快速创建 UI 操作界面
    在开发Web应用或服务时,通常会提供不同数量的API接口给客户端或其他第三方使用,当API数量达到一定数量的时候,在处理接口间的调用链以及参数关系时就会变得异常麻烦。在这种情况下便可通过Bittly的面板功能将这些API结构进行组装整理起来组成一个UI控制面板,从而......
  • Android面试:OkHttp 详解
    引言        在Android开发中,网络请求是不可或缺的一部分。OkHttp作为一款强大的HTTP客户端库,以其高效、易用和灵活的特点,成为了Android开发者的首选。本文将深入解析OkHttp的内部机制,包括其架构、基本使用、核心组件以及如何通过扩展来实现更丰富的功能。1......
  • XMLHttpRequest、Fetch、Axios和AJAX的关系
    一、基于http协议用于前后端通信的工具1、XMLHttpRequest(原生JS对象)XMLHttpRequest(XHR)是原生JavaScript对象。通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL,获取数据。特性:浏览器广泛支持功能丰富:可以跟踪请求的状态、支持进度事件、文件上传、同步......
  • Linux读写者管理sharefile文件,多个客户端向服务器输送信息,由服务器为中转站将信息存入
    Linux系统读写者将文件存入sharefile文件中,同时由多个客户端向服务器输入通信信息,并由服务器为中转站,将信息传入sharefile文件中(由于读写者存入sharefile文件的路径问题,sharefile文件要放入Linux虚拟机的“公共”文件中,不然不能运行,同时要将文件分开每个Makefile文件都要放在对......
  • python爬虫连载 HTTP响应头
    响应头服务器收到请求后,会对客户端进行响应。1HTTP/1.1表示使用HTTP1.1协议标准,200OK说明请求成功。2Date表示消息产生的日期和时间。3Content-Type实体报头域用于指明发送给接收者的实体正文的媒体类型。texthtm1:charset=utf-8代表HTML文本文档,UTF-8编码。4Transfer-E......
  • 一个.NET开源、快速、低延迟的异步套接字服务器和客户端库
    前言最近有不少小伙伴在问:.NET有什么值得推荐的网络通信框架?今天大姚给大家分享一个.NET开源、免费(MITLicense)、快速、低延迟的异步套接字服务器和客户端库:NetCoreServer。项目介绍NetCoreServer是一个.NET开源、免费(MITLicense)、快速、低延迟的异步套接字服务器和客户端库。它支......
  • Mac vscode 每次打开的终端,执行node命令都报command not found: node
    先说问题,答案放在后面自从上次升级node后,每次vscode打开终端都会报npmwarnclinpmv10.8.2doesnotsupportNode.jsv18.14.2.Thisversionofnpmsupportsthefollowingnodeversions:`^18.17.0||>=20.5.0`.Youcanfindthelatestversionathttps://nodejs.or......