Appearance
基本使用
js
const urlParse = require('url')
const http = require('http')
const server = http.createServer((req, res) => {
// http://127.0.0.1:3000/foo?bar=bar&baz=baz#hash=hash
const {
url, // /foo?bar=bar&baz=baz,拿不到 hash
method, // GET
// 所有请求头的 key 都是小写的
// {
// host: '127.0.0.1:3000',
// connection: 'keep-alive',
// // ...
// }
headers,
httpVersion // 2.0
} = req
// 处理 query
// const query = {}
// url.replace(/([^&?=]+)=([^&?=]+)/g, (_, $1, $2) => {
// query[$1] = $2
// })
// 使用 Node 自带的 url 模块解析 url
// hostname // 主机名
// query // 查询参数
// pathname 请求路径
const { query, pathname, hostname } = urlParse.parse(url, true) // true 表示将 query 转成对象
// req 是一个可读流
const ary = []
// 如果流中数据为空,内部调用 push(null),只要调用 push(null) 一定触发 end 事件。
req.on('data', chunk => {
ary.push(chunk)
})
// 没有数据也会触发 end 事件
req.on('end', () => {
// console.log(Buffer.concat(ary).toString())
})
// res 是一个可写流,响应行 响应头 响应体 顺序不能发生变化
res.statusCode = 200
// res.statusMessage = 'OK' // 一般不设置状态码
res.setHeader('Foo', 'foo')
res.write('foo') // 分段响应 Transfer-Encoding: chunked
res.write('bar')
res.end() // 标识响应结束
})
// 监听请求到来,等价于上面。
// server.on('request', (req, res) => {})
let port = 3000
server.listen(port, () => {
console.log(`server start: http://127.0.0.1:${ port }`)
})
server.on('error', err => {
// 解决端口占用
if (err.code === 'EADDRINUSE') {
server.listen(++port)
}
})