1. http 服务端
let http = require('http');
let port = 3000;
http.createServer((req,res)=>{
//监听函数,当请求到来时会执行回调函数
//req 代表是客户端,他是一个可读流
//res 代表是服务端,他是一个可写流
console.log("star1")
res.setHeader('Content-Type','text/plain;charset=utf8')
res.write("女孩");
res.end(); // 调用end后结束响应
}).listen(port,()=>{
console.log(`服务器已经启动在${port}上`)
});
//端口号尽量使用3000以上的端口号
大概代码执行流程:
http.createServer() 返回新建的 http.Server 实例。http.Server 继承自net.Server。requestListener 是一个自动添加到到 'request' 事件的函数。
'request' 事件 每次请求的时候都会触发。http服务是以request为单位进行服务的。
http.IncomingMessage 对象,它可用于访问本次,请求的请求方法、消息头、以及数据(图中将,请求头与数据拆分开)。
http.ServerResponse 对象,服务端通过http.ServerResponse 实例,来给客户端(数据请求方)返回本次数据。包括响应头,响应体(内部通过socket来发送信息)。
http服务端:在TCP模块套接字 socket 上,将接受的数据解析出请求报文头和报文主体,将返回的响应报文头和报文主体组装成数据发送出去。
1.1 请求:
请求报文由以下组成
- 报文首部:请求方法、请求 URI、协议版本、可选的请求首部字段等
- 空行
- 报文主体:内容实体构成数据
node http 模块 在TCP连接的读操作上,将数据解析成(以空行分割,报文头和报文体):
报文头部分:
req.method
req.httpVersionMajor
req.httpVersionMinor
req.httpVersion
req.upgrade
...
req.headers = {
Content-Length: 15
Content-Type: application/x-www-form-urlencoded
... ...
}
//
报文主体部分:
一个可读流对象req,可以继续报文主体数据的读取
1.2响应
服务端通过http.ServerResponse 实例,来向客户端(数据请求方)返回本次请求数据。包括响应头,响应体(内部通过socket来发送信息)。
node http 模块 在TCP连接的写操作上,将数据写缓存拼接(以空行拼接,报文头和报文体)成:
//中间有个空行
"HTTP/1.1 200 OK
Date: Sat, 30 Nov 2019 05:10:05 GMT
Connection: close
Content-Length: 25
"
+ 请求体部分数据或全部数据
通过的方法
// 具体使用参考文档
// 设置头部,头部并没有发送
response.setHeader(name, value)
// 设置头部,向请求发送响应头,此方法只能在消息上调用一次,
//并且必须在调用 response.end() 之前调用。
response.writeHead()
// 如果调用此方法并且尚未调用response.writeHead(),则将切换到隐式响应头模式并刷新隐式响应头
// 这会发送一块响应主体。 可以多次调用该方法以提供连续的响应主体片段。
response.write()
// 此方法向服务器发出信号,表明已发送所有响应头和主体,该服务器应该视为此消息已完成。
// 必须在每个响应上调用此 response.end() 方法。
response.end()
2. http 客户端
客户端向 HTTP服务器发起请求:
let http = require('http')
let options = {
host: 'localhost',
port: 8080,
method: 'POST',
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
}
// 请求并没有 发出 req 是个可写流
let req = http.request(options)
req.on('response', res => {
console.log(res.headers)
let buf = []
res.on('data', data => {
buf.push(data)
})
res.on('end', () => {
console.log(Buffer.concat(buf).toString())
})
})
// write 向请求体写数据
req.write('name=luoxiaobu&title=http')
// 实际的请求头将会与第一个数据块一起发送,或者当调用 request.end() 时发送。
req.end()
大概代码执行流程
http.request() 返回 http.ClientRequest 类的实例。http.ClientRequest 内部创建了一个socket来发起请求。
ClientRequest 实例是可以看做可写流。如果需要使用 POST 请求上传文件,则写入到 ClientRequest 对象。
response事件 每次服务器端有数据返回响应时都会触发。
http.IncomingMessage 对象,它可用于访问本次服务器端返回的,响应状态、消息头、以及数据。
http客户端:在TCP模块套接字 socket 上,将求报文头和报文主体组装成数据发送出去,将接受的数据解析出响应报文头和报文主体,。
2.1 请求:
node http 模块 在TCP连接的写操作上,将数据缓存拼接(以空行拼接,报文头和报文体)成:
//中间有个空行
"POST / HTTP/1.1
content-type: application/x-www-form-urlencoded
Host: localhost:8080
Connection: close
Transfer-Encoding: chunked
"
+ 请求体部分数据或全部数据
通过的方法
// 具体使用参考文档
const postData = querystring.stringify({
'msg': '你好世界'
});
const options = {
hostname: 'localhost:8080',
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
// 内部会处理 options 解析出头部
const req = http.request(options, (res) => {
});
// 这会发送一块响应主体。 可以多次调用该方法以提供连续的响应主体片段。
response.write()
// 此方法向服务器发出信号,表明已发送所有响应头和主体,该服务器应该视为此消息已完成。
//必须在每个响应上调用此 response.end() 方法。
response.end()
2.2 响应
响应报文图:
响应报文由以下组成
- 报文首部:协议版本、状态码(表示请求成功或失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段
- 空行
- 报文主体:实体主体构成
node http 模块 在TCP连接的读操作上,将数据解析成:
报文头部分:
res.statusCode = statusCode;
res.statusMessage = statusMessage;
res.httpVersionMajor
res.httpVersionMinor
res.httpVersion
res.upgrade
...
res.headers = {
Content-Length: 15
Content-Type: application/x-www-form-urlencoded
... ...
}
//
报文主体部分:
一个可读流对象,可以继续报文主体数据的读取
参考:nodejs.cn/api/http.ht…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!