Node学习十四 —— 使用node创建HTTP请求
创建HTTP连接
Node擅长处理I/O操作,所以它不仅合适提供HTTP服务,也适合使用这些服务。接下来你将学习使用http
模块和第三方模块执行和控制http请求。
在HTTP协议中,有两个重要的属性:URL和方法。最常见的是GET、POST方法,还有PUT等别的方法。
一、创建GET请求
const http = require('http');const options = {host: 'localhost',port: 1234,path: '/'
}http.get(options, (res) => {console.log(res);
})
在上面这个例子中,使用TCP端口1234向主机名localhost
和路径/
执行GET请求(localhost:1234/
)。回调函数会在服务器响应到达的时候处理响应对象。
二、使用其他HTTP动词
2.1 发送POST请求
http.get 是通用的 http.request 的快捷方式,其选项如下:
- host——请求目标的主机名或者IP地址
- port——远程服务器的TCP端口号
- method——指定HTTP请求方法的字符串,值就是GET/POST/PUT/PATCH/DELETE等关键词。
- path——请求的路径,可以包含一个查询字符串和一个分隔符:/index?id=1
- headers——配置请求头
http.request 方法会返回一个 http.ClientRequest 对象,它是一个可写流,可以使用这个流发送数据,所发送的数据是请求主体数据的一部分,当完成向请求主体中写入数据时,要结束数据流来终止请求。
完整的请求,你可以这么写:
const http = require('http');const options = {host: 'localhost',port: 1234,path: '/',method: 'POST'
}// 发送请求,监听响应
const req = http.request(options, (response) => {console.log(response.statusCode);console.log(response.headers);response.setEncoding('utf-8');response.on('data', (chunk) => {console.log('BODY : ' + chunk);})
})req.write('This is a request');
req.end();
http.request 返回ClientRequest对象,可以通过req.write()
方法将请求主体写入该对象,可以传入一个经过编码的字符串,或者缓冲区。必须使用end()
去结束请求,不然会被认为请求不完整,从而不会处理该请求。
如果服务器正常工作,会返回一个响应,客户端接收到响应触发response
事件:
req.on('response', (res) => {console.log(res);
})
2.2 查看响应对象
响应对象是ClientResponse的一个实例,主要属性有:
- statusCode——HTTP状态码
- httpVersion——HTTP版本号
- headers——响应头
2.3 获取响应主体
响应主体并不会在请求的response事件发生时出现,而是需要监听data事件:
http.request(options, (response) => {response.setEncoding('utf8');response.on('data', (data) => {console.log(data);})
})
响应主题可以是一个缓冲区,但是如果指定了编码格式,那么就是一个编码字符串了。
2.4 以流的方式传送响应主体
HTTP响应是一个可读流,表示响应主体数据流。可以将一个可读流送入一个可写流中,例如一个HTTP请求或者一个文件:
const http = require('http');
const fs = require('fs');
const options = {host: 'localhost',port: 1234,path: '/',method: "GET"
}const file = fs.createWriteStream('./test.text');http.request(options, (res) => {res.pipe(file);
}).end();
上面创建了一个可写文件流,并将响应体写入文件。
当响应到达,文件流打开,响应体写入;当响应主体结束的时候,文件流也结束,文件流被关闭。
三、使用 HTTP.Agent 维护套接字
在创建HTTP请求的时候,Node在内部使用了一个代理。
代理是Node中的一种实体,该实体用来给你创建请求,它负责维护一个套接字池,对指定的主机名和端口对,套接字池中包含已经被打开但是未被使用的连接。
当出现新的HTTP请求时,代理要求连接保持活跃状态;当请求结束,并且在套接字上没有额外的请求等待释放时,套接字就会被关闭,而不用手动关闭。
当创建了一个请求并选择了一个可用的套接字,或者为该请求创建了一个新的连接时,http.ClientRequest 会发射socket事件。在请求结束之后,套接字会在发射close事件或agentRemove事件时从套接字池中被删除。
四、应用第三方请求模块简化HTTP请求
Node的HTTP客户端非常强大,但是用起来很麻烦:
- 必须提供一个配置对象,需要所有选项,包括被分割的URL。
- 如果希望处理响应体,需要专门获取响应体。
- 如果是重定向响应,需要人工处理该响应。
通过使用 request 模块可以简化操作。
1. 安装和应用 request 模块
使用npm在当前目录下安装该模块
npm install request
然后使用:
const r = require('request');
之后只需要提供URL和回调就可以创建请求了
request('localhost:1234', (error,res,body) => {...
})
如果按上述代码发送请求,默认为GET请求吗,如果想要使用其他HTTP动词,例如post:request.put(url);
还可以用option
对象来替代URL,可选参数可以查看官方文档。
2. 创建测试服务器
- 服务器端代码
const http = require('http');
const server = http.createServer();// 监听请求
server.on("request", (req, res) => {// 回送一个消息const printBack = function () {res.writeHead(200, {'Content-Type': 'text/plain'});res.end(JSON.stringify({URL: req.url,method: req.method,Headers: req.headers}))}// 路由switch (req.url) {// 重定向case '/redirect':res.writeHead(301, { "Location": '/' })res.end();break;// 打印请求体case '/print/body':req.setEncoding('utf8');let body = "";req.on('data', (data) => {body += data;});// 结束之后,响应以发送body结束req.on('end', () => {res.end(JSON.stringify(body));})break;// 默认default:printBack();break;}
})server.listen(1234);
- 客户端代码
const request = require('request');
const inspect = require('util').inspect;request.get('http://localhost:1234/print/body', (err, res, body) => {if(err) {throw err;}console.log(inspect({err: err,res: {statusCode: res.statusCode},body: JSON.parse(body)}))
})
3. 跟随重定向
request 的特性之一是它在默认情况下能够跟随重定向。可以用上面的代码来观察这个特征:
当请求路径为/redirect
时,可以用301重定向响应码做出响应。可以用客户端来查看跟随上述URL的请求:
将请求路径修改为/redirect
,可以在客户端看到返回信息中路径为/
而不是/redirect
。
如果你希望发生重定向的时候得到通知,可以把请求选项中的followRedirect
设置为 false 。
4. 使用option
const options = {url: 'http://localhost:1234',method: 'POST',headers: {'...': '...'}
}
request(options, function(err, res, body){...........
})
5. 对请求体进行编码
有时候需要在请求主体上发送一些数据,可以使用表单编码对请求体进行编码:
const body = {a: 1,b: 2
};
const options = {url: '...',form: body// 还可以采用json编码,如下:// json: body
}
6. 流式传送
请求返回的是一个客户端请求对象,可以将该对象传入可写流当中,甚至可以将请求对象传入另一个请求。
传入文件
request.get('...').pipe(fs.createWriteStream('...'));
传入另一个请求
request.get('...').pipe(request.post('...'));
Node学习十四 —— 使用node创建HTTP请求相关推荐
- OpenCV与图像处理学习十四——SIFT特征(含代码)
OpenCV与图像处理学习十四--SIFT特征(含代码) 一.SIFT算法 二.SIFT实现过程 三.代码实现 一.SIFT算法 SIFT, 即尺度不变特征变换算法(Scale-invariant f ...
- PyTorch框架学习十四——学习率调整策略
PyTorch框架学习十四--学习率调整策略 一._LRScheduler类 二.六种常见的学习率调整策略 1.StepLR 2.MultiStepLR 3.ExponentialLR 4.Cosin ...
- C1认证学习十四、十五(算法常识、HTML Head 头)
C1认证学习十四.十五(算法常识.HTML Head 头) 文章目录 C1认证学习十四.十五(算法常识.HTML Head 头) 十四(算法常识) 任务背景 任务目标 查找算法 1.顺序查找 2.二分 ...
- 如何用mysql创建orders表_MySQL学习十四创建和操纵表
摘要: 本篇博客仅作为笔记,如有侵权,请联系,立即删除(网上找博客学习,然后手记笔记,因纸质笔记不便保存,所以保存到网络笔记). 本博讲述表的创建.更改和删除的基本知识. 一.创建表 MySQL不仅用 ...
- python基础学习十四:面向对象三大特性之继承
一.继承的基本概念 Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法,具体如下: # ⽗类A class A(object):def __init__(self ...
- AppArmor零知识学习十四、实操与实践(2)
本文内容参考: Linux安全模块AppArmor总结-CSDN博客, apparmor首页.文档和下载 - 应用程序访问控制系统 - OSCHINA - 中文开源技术交流社区, AppArmor · ...
- Netty学习十四:内存管理之Recycler 对象池
一.Recycler 使用示例 Netty除了内存池技术外,还有另一种池化技术:Recycler对象池. 以下是Recycler 的演示示例,假设有一个User类,需要实现User对象的复用: pub ...
- 学习十四-Python爬虫一
爬虫 (WebSpider) 所谓爬虫,就是把互联网看成一张网,而爬虫就行蜘蛛一样在网上想收集猎物一样收集互联网中我们想要的信息. Python 访问互联网 使用Python编写一只爬虫,先解决的问题 ...
- Python学习十四:filter()
Python 中内置了filter()函数用于过滤序列. 使用方法: filter()接收一个函数和一个序列. filter()把传入的函数依次作用于每一个元素,然后依据返回值是True还是False ...
最新文章
- [Redis]Redis章2 Redis 持久化
- 通达信版弘历软件指标_通达信软件指标编写基础教程,10个指标源码祝你股市一帆风顺...
- 有效运维的 on-call 机制
- android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...
- Flex 最全的换行 制表符 回车 空格 特殊符号
- 测一下markdown之第一篇博文
- JAVA JDK 官网安装包启动后没反应
- 鲁冠球:冲向世界的打铁匠
- 设置美团用户cookie实现用户登录
- 中国大学MOOC-陈越、何钦铭-数据结构-2020春期末考试【个人完整题解记录-判断选择部分】
- java中图片排版,如何快速排版PPT中的图片?这样做真实而不失美感
- Android OnDeviceAppPrediction 优化
- 樱花樱花想见你 (中日歌词+罗马音+音译)
- 2022年全球与中国电缆悬挂夹市场现状及未来发展趋势
- MySQL中DATE_FORMAT()函数的说明和简介
- StarUML3.0的破解方法
- node.js express配置响应头解决跨域问题
- Golang实习蓝湖二面
- 光和储能结合模型(Matlab代码实现)
- 岁月,依一抹浅香于心间