Chuyển đến nội dung chính

第 7 課:HTTP/HTTPS 與 HTTP/2

http.createServer、路由、中間件模式從頭開始。 HTTPS/TLS 設定。 HTTP/2 伺服器推送。請求/回應處理,分塊傳輸。保持活動狀態,連線池。

💻 程式設計 — 第 7 課 第 7 課:HTTP/HTTPS 與 HTTP/2

Node.js 核心:從基礎到高級

第 2 部分:核心模組深入探討

亞洲開發網

1. 基本HTTP伺服器

import { createServer, IncomingMessage, ServerResponse } from 'node:http'

const server = createServer((req: IncomingMessage, res: ServerResponse) => {
  // Request info
  const { method, url, headers } = req
  console.log(`${method} ${url}`)

  // Routing cơ bản
  if (method === 'GET' && url === '/') {
    res.writeHead(200, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify({ message: 'Hello World' }))
  } else if (method === 'GET' && url === '/health') {
    res.writeHead(200)
    res.end('OK')
  } else {
    res.writeHead(404)
    res.end('Not Found')
  }
})

server.listen(3000, () => console.log('Server on :3000'))

2. 讀取請求體

async function parseBody(req: IncomingMessage): Promise<unknown> {
  const chunks: Buffer[] = []
  for await (const chunk of req) {
    chunks.push(chunk as Buffer)
  }
  const body = Buffer.concat(chunks).toString()
  const contentType = req.headers['content-type'] || ''

  if (contentType.includes('application/json')) {
    return JSON.parse(body)
  }
  return body
}

// Sử dụng
const server = createServer(async (req, res) => {
  if (req.method === 'POST' && req.url === '/api/users') {
    const body = await parseBody(req) as { name: string }
    res.writeHead(201, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify({ id: 1, name: body.name }))
  }
})

3.HTTPS/TLS伺服器

import { createServer } from 'node:https'
import { readFileSync } from 'node:fs'

const server = createServer({
  key: readFileSync('certs/private-key.pem'),
  cert: readFileSync('certs/certificate.pem'),
  ca: readFileSync('certs/ca.pem'),
}, (req, res) => {
  res.writeHead(200)
  res.end('Secure!')
})

server.listen(443)

4.HTTP/2伺服器

import { createSecureServer } from 'node:http2'
import { readFileSync } from 'node:fs'

const server = createSecureServer({
  key: readFileSync('certs/key.pem'),
  cert: readFileSync('certs/cert.pem'),
  allowHTTP1: true,
})

server.on('stream', (stream, headers) => {
  const path = headers[':path']
  const method = headers[':method']

  stream.respond({
    'content-type': 'application/json',
    ':status': 200,
  })
  stream.end(JSON.stringify({ path, method, protocol: 'h2' }))
})

server.listen(8443)

5. 取得(內建)

// Node.js 22+ — fetch là global (dựa trên undici)
const response = await fetch('https://api.github.com/users/octocat', {
  headers: { 'User-Agent': 'Node.js' },
  signal: AbortSignal.timeout(5000), // Timeout 5s
})

if (!response.ok) throw new Error(`HTTP ${response.status}`)
const data = await response.json()

6. 連接池

import { Agent } from 'node:http'

// Custom agent với connection pooling
const agent = new Agent({
  keepAlive: true,
  keepAliveMsecs: 30000,
  maxSockets: 50,
  maxFreeSockets: 10,
})

// Dùng với fetch (undici)
import { Agent as UndiciAgent, setGlobalDispatcher } from 'undici'

setGlobalDispatcher(new UndiciAgent({
  connections: 50,
  pipelining: 10,
  keepAliveTimeout: 30000,
}))

下一篇: 加密、作業系統和流程 — 雜湊、加密、子程序。