HTTP
基本使用
js
const http = require('http')
// 创建一个 http 对应的服务器
const server = http.createServer((request, response) => {
// request 对象中包含本次客户端请求的所有信息
// 请求的 url
// 请求的 method
// 请求的 headers
// 请求携带的数据
// response 对象用于给客户端返回结果的
response.end('Hello World')
})
// 开启对应的服务器, 并且告知需要监听的端口
// 监听端口时, 监听 1024 以上的端口, 666535 以下的端口
// 1025~65535 之间的端口
// 2 个字节 => 256\*256 => 65536 => 0~65535
server.listen(8000, () => {
console.log('服务器已经开启成功了~')
})
创建多个服务器
js
const http = require('http')
// 1.创建一个服务器
const server1 = http.createServer((req, res) => {
res.end('2000端口服务器返回的结果~')
})
server1.listen(2000, () => {
console.log('2000端口对应的服务器启动成功~')
})
// 2.创建第二个服务器
const server2 = http.createServer((req, res) => {
res.end('3000端口服务器返回的结果~')
})
server2.listen(3000, () => {
console.log('3000端口对应的服务器启动成功~')
})
// 3.创建第三个服务器
// const server3 = new http.Server()
request
js
const http = require('http')
// 1.创建server服务器
const server = http.createServer((req, res) => {
// request对象中包含哪些信息?
// 1.url信息
console.log(req.url)
// 2.method信息(请求方式)
console.log(req.method)
// 3.headers信息(请求信息)
console.log(req.headers)
res.end('hello world aaaa')
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
区分不同的 url
js
const http = require('http')
// 1.创建server服务器
const server = http.createServer((req, res) => {
const url = req.url
if (url === '/login') {
res.end('登录成功~')
} else if (url === '/products') {
res.end('商品列表~')
} else if (url === '/lyric') {
res.end('天空好想下雨, 我好想住你隔壁!')
}
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
区分不同的 method
在 Restful 规范(设计风格)中,我们对于数据的增删改查应该通过不同的请求方式:
- GET:查询数据;
- POST:新建数据;
- PATCH:更新数据;
- DELETE:删除数据;
所以,我们可以通过判断不同的请求方式进行不同的处理。
- 比如创建一个用户:
- 请求接口为 /users;
- 请求方式为 POST 请求;
- 携带数据 username 和 password;
js
const http = require('http')
// 1.创建server服务器
const server = http.createServer((req, res) => {
const url = req.url
const method = req.method
if (url === '/login') {
if (method === 'POST') {
res.end('登录成功~')
} else {
res.end('不支持的请求方式, 请检测你的请求方式~')
}
} else if (url === '/products') {
res.end('商品列表~')
} else if (url === '/lyric') {
res.end('天空好想下雨, 我好想住你隔壁!')
}
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
query 参数
js
const http = require('http')
const url = require('url')
const qs = require('querystring')
// 1.创建server服务器
const server = http.createServer((req, res) => {
// 1.参数一: query类型参数
// /home/list?offset=100&size=20
// 1.1.解析url
const urlString = req.url
const urlInfo = url.parse(urlString)
// 1.2.解析query: offset=100&size=20
const queryString = urlInfo.query
const queryInfo = qs.parse(queryString)
console.log(queryInfo.offset, queryInfo.size)
res.end('hello world aaaa bbb')
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
body 参数
js
const http = require('http')
const url = require('url')
const qs = require('querystring')
// 1.创建server服务器
const server = http.createServer((req, res) => {
// 获取参数: body参数
req.setEncoding('utf-8')
// request对象本质是上一个readable可读流
let isLogin = false
req.on('data', (data) => {
const dataString = data
const loginInfo = JSON.parse(dataString)
if (loginInfo.name === 'coderwhy' && loginInfo.password === '123456') {
isLogin = true
} else {
isLogin = false
}
})
req.on('end', () => {
if (isLogin) {
res.end('登录成功, 欢迎回来~')
} else {
res.end('账号或者密码错误, 请检测登录信息~')
}
})
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
headers 参数
content-type 是这次请求携带的数据的类型:
- application/x-www-form-urlencoded:表示数据被编码成以 '&' 分隔的键 - 值对,同时以 '=' 分隔键和值
- application/json:表示是一个 json 类型;
- text/plain:表示是文本类型;
- application/xml:表示是 xml 类型;
- multipart/form-data:表示是上传文件;
content-length:文件的大小长度
keep-alive:
- http 是基于 TCP 协议的,但是通常在进行一次请求和响应结束后会立刻中断;
- 在 http1.0 中,如果想要继续保持连接: ✓ 浏览器需要在请求头中添加 connection: keep-alive; ✓ 服务器需要在响应头中添加 connection:keey-alive; ✓ 当客户端再次放请求时,就会使用同一个连接,直接一方中断连接;
- 在 http1.1 中,所有连接默认是 connection: keep-alive 的; ✓ 不同的 Web 服务器会有不同的保持 keep-alive 的时间; ✓ Node 中默认是 5s 中;
accept-encoding:告知服务器,客户端支持的文件压缩格式,比如 js 文件可以使用 gzip 编码,对应 .gz 文件;
accept:告知服务器,客户端可接受文件的格式类型;
user-agent:客户端相关的信息;
js
const http = require('http')
const url = require('url')
const qs = require('querystring')
// 1.创建server服务器
const server = http.createServer((req, res) => {
console.log(req.headers)
console.log(req.headers['content-type'])
// cookie/session/token
const token = req.headers['authorization']
console.log(token)
res.end('查看header的信息~')
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
响应方式
如果我们希望给客户端响应的结果数据,可以通过两种方式:
- Write 方法:这种方式是直接写出数据,但是并没有关闭流;
- end 方法:这种方式是写出最后的数据,并且写出后会关闭流;
如果我们没有调用 end 和 close,客户端将会一直等待结果:
- 所以客户端在发送网络请求时,都会设置超时时间。
js
const http = require('http')
// 1.创建server服务器
const server = http.createServer((req, res) => {
// res: response对象 => Writable可写流
// 1.响应数据方式一: write
res.write('Hello World')
res.write('哈哈哈哈')
// // 2.响应数据方式二: end
res.end('本次写出已经结束')
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
响应状态
Http 状态码(Http Status Code)是用来表示 Http 响应状态的数字代码:
- Http 状态码非常多,可以根据不同的情况,给客户端返回不同的状态码;
- MDN 响应码解析地址:https://developer.mozilla.org/zh-CN/docs/web/http/status
js
const http = require('http')
// 1.创建server服务器
const server = http.createServer((req, res) => {
// 响应状态码
// 1.方式一: statusCode
// res.statusCode = 403
// 2.方式二: setHead 响应头
res.writeHead(401)
res.end('hello world aaaa')
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
响应 header
返回头部信息,主要有两种方式:
- res.setHeader:一次写入一个头部信息;
- res.writeHead:同时写入 header 和 status;
js
const http = require('http')
// 1.创建server服务器
const server = http.createServer((req, res) => {
// 设置header信息: 数据的类型以及数据的编码格式
// 1.单独设置某一个header
// res.setHeader('Content-Type', 'text/plain;charset=utf8;')
// 2.和http status code一起设置
res.writeHead(200, {
'Content-Type': 'application/json;charset=utf8;',
})
const list = [
{ name: 'why', age: 18 },
{ name: 'kobe', age: 30 },
]
res.end(JSON.stringify(list))
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})
发送 Axios
js
const axios = require('axios')
axios.get('http://localhost:8000').then((res) => {
console.log(res.data)
})
发送 http 请求
js
const http = require('http')
// 1.使用http模块发送get请求
// http.get('http://localhost:8000', (res) => {
// // 从可读流中获取数据
// res.on('data', (data) => {
// const dataString = data.toString()
// const dataInfo = JSON.parse(dataString)
// console.log(dataInfo)
// })
// })
// 2.使用http模块发送post请求
const req = http.request(
{
method: 'POST',
hostname: 'localhost',
port: 8000,
},
(res) => {
res.on('data', (data) => {
const dataString = data.toString()
const dataInfo = JSON.parse(dataString)
console.log(dataInfo)
})
}
)
// 必须调用end, 表示写入内容完成
req.end()
上传图片
js
const http = require('http')
const fs = require('fs')
// 1.创建server服务器
const server = http.createServer((req, res) => {
req.setEncoding('binary')
const boundary = req.headers['content-type']
.split('; ')[1]
.replace('boundary=', '')
console.log(boundary)
// 客户端传递的数据是表单数据(请求体)
let formData = ''
req.on('data', (data) => {
formData += data
})
req.on('end', () => {
console.log(formData)
// 1.截图从image/jpeg位置开始后面所有的数据
const imgType = 'image/jpeg'
const imageTypePosition = formData.indexOf(imgType) + imgType.length
let imageData = formData.substring(imageTypePosition)
// 2.imageData开始位置会有两个空格
imageData = imageData.replace(/^\s\s*/, '')
// 3.替换最后的boundary
imageData = imageData.substring(0, imageData.indexOf(`--${boundary}--`))
// 4.将imageData的数据存储到文件中
fs.writeFile('./bar.png', imageData, 'binary', () => {
console.log('文件存储成功')
res.end('文件上传成功~')
})
})
})
// 2.开启server服务器
server.listen(8000, () => {
console.log('服务器开启成功~')
})