Node.js-http模块

HTTP 协议

概念
  • HTTP(hypertext transport protocol)协议;中文叫超文本传输协议,是一种基于TCP/IP的应用层通信协议
  • 这个协议详细规定了 浏览器 和万维网 服务器 之间互相通信的规则。
  • 协议中主要规定了两个方面的内容
    • 客户端:用来向服务器发送数据,可以被称之为请求报文
    • 服务端:向客户端返回数据,可以被称之为响应报文
客户端请求规范(请求报文组成)
1. 请求行
  • 由三部分组成:

    • 请求方法
    • 常用的请求方法
    • GET:获取资源
    • POST:提交资源
    • PUT:更新资源
    • DELETE:删除资源
    • HEAD:获取资源的元信息
    • OPTIONS:获取服务器支持的请求方法
    • 请求URL:统一资源定位符
js 复制代码
http://www.example.com:8080/path/to/resource?query=param#fragment
// 协议:http(https、ftp、ssh等) 通信协议
// 域名:www.example.com 服务器地址
// 端口:8080 端口号,默认端口号为80,可省略
// 路径:/path/to/resource 资源位置
// 查询参数:?query=param 用于向服务器传递额外信息
// 锚点:#fragment 页面内定位(浏览器端使用),哈希(锚点链接)
  • HTTP 协议版本
  • 例如:HTTP/1.1或HTTP/2
2.请求头
  • 采用键值对格式:头名: 头值
头名 作用 示例
Host 目标主机 Host: www.example.com
User-Agent 客户端标识,用户代理,客户端字符串标识,服务器可以通过这个标识来识别这个请求来自User-Agent,哪个客户端 ,一般在PC端和手机端的区分 User-Agent: Mozilla/5.0
Accept 可接收的响应类型 Accept: text/html
Accept-Encoding 可接受的压缩编码类型 Accept-Encoding: gzip, deflate
Cookie 客户端存储信息 Cookie: session_id=abc123
Content-Type 请求体类型 Content-Type: application/json
Authorization 身份验证 Authorization: Bearer token
Connection 连接的设置 keep-alive(保持连接);close(关闭连接) Connection: keep-alive
Cache-Control 缓存控制 max-age = 0 (没有缓存) Cache-Control: no-cache
Upgrade-Insecure-Requests 将网页中的http请求转化为https请求(很少用)老网站升级 Upgrade-Insecure-Requests: 1
Accept-Language 可接受的语言 Accept-Language: en-US,en;q=0.9
3.空行
  • 用于分隔请求头和请求体
4.请求体

包含客户端发送给服务器的数据:

​- ​GET请求​​:通常没有请求体

  • POST/PUT请求:包含表单数据、JSON、文件等
  • 用于向服务器提交数据,例如表单数据、JSON数据等。
  • 请求体的格式取决于请求头中的Content-Type字段。
  • 常见的请求体格式有:
    • application/x-www-form-urlencoded:表单数据
    • multipart/form-data:文件上传
    • 表单:name=John&age=30
    • JSON:{"name": "John", "age": 30}
    • XML:John
服务端响应规范(响应报文组成)
1.状态行(Status Line)
  • 由三部分组成:

    • HTTP协议版本
      • HTTP/1.1:HTTP协议版本号
    • 状态码(Status Code)
    js 复制代码
    //1xx  信息响应 ,请求已接收,继续处理
    //2xx  成功响应,请求成功处理
    //3xx  重定向,需要进一步操作
    //4xx  客户端错误,客户端请求错误
    //5xx  服务器错误,服务器处理错误
    //例如:
    //200 OK:请求成功
    //301 Moved Permanently:永久重定向
    //404 Not Found:资源不存在
    //500 Internal Server Error:服务器内部错误
    • 状态描述(Reason Phrase)
      • OK:请求成功
      • Not Found:请求的资源不存在
      • Internal Server Error:服务器内部错误
      • Bad Request:客户端请求错误
      • Unauthorized:未授权
      • Forbidden:禁止访问
  • 响应头
    服务器返回的元数据信息

常见的响应头 作用 示例
Content-Type 响应体类型 Content-Type: text/html;charset=utf-8,设置响应体的数据类型以及字符集,响应体为html,字符集utf-8
Content-Length 响应体的长度,单位为字节 Content-Length: 1234
Set-Cookie 设置客户端Cookie Set-Cookie: session_id=abc123
Cache-Control 缓存控制 Cache-Control: max-age=3600
Location 重定向目标 Location: /new-path
  • 空行
    分隔响应头和响应体的空行
  • 响应体
    服务器返回的实际内容
  • HTML页面
  • JSON/XML数据
  • 图片/视频等二进制文件
  • JavaScript/CSS等资源

MIME类型处理

HTTP通过Content-Type头指定数据的MIME类型

文件类型 MIME类型 说明
HTML text/html 网页内容
CSS text/css 样式表
JavaScript application/javascript 脚本
JSON application/json 结构化数据
TEXT text/plain 文本
JPEG image/jpeg 图片
PDF application/pdf 文档
XML application/xml XML数据
ZIP application/zip 压缩文件
GIF image/gif GIF图片
PNG image/png PNG图片
SVG image/svg+xml SVG图片
MP3 audio/mpeg 音频
MP4 video/mp4 视频

连接管理

HTTP协议支持不同的连接策略

  • HTTP/1.0:短连接(每次请求新建连接)
  • HTTP/1.1:持久连接(默认启用Keep-Alive)
  • HTTP/2:多路复用(多个请求共享一个连接)
  • HTTP/3:QUIC协议(基于UDP的快速传输协议)
Node.js 创建 HTTP 服务

Node.js 内置的 http 模块可以轻松创建高性能的 HTTP 服务器

js 复制代码
// 1.导入 http 模块
const http = require('http');


//2. 创建服务对象 create 创建 server 服务
//request 意为请求. 是对请求报文的封装对象, 通过 request 对象可以获得请求报文的数据
//response 意为响应. 是对响应报文的封装对象, 通过 response 对象可以设置响应报文
const server = http.createServer((req, res) => {
    // 设置响应头
    //res.setHeader('Content-Type', 'text/plain');
     // 设置响应头防止中文乱码
     res.setHeader('content-type','text/html;charset=utf-8');
    // 发送响应
     res.end('哈哈哈Hello, World!\n');

})
//3. 启动服务器监听指定端口
server.listen(3000, () => {
  console.log('服务启动成功, 端口号为 3000')  
})

注意:

  • 1.响应内容中文乱码的解决办法
js 复制代码
// 设置响应头防止中文乱码
res.setHeader('content-type','text/html;charset=utf-8');
  • 2.端口号被占用

    解决办法:修改端口号

  • 3.HTTP 协议默认端口是 80 。HTTPS 协议的默认端口是 443, HTTP 服务开发常用端口有 3000,

    8080,8090,9000 等

获取 HTTP 请求报文(请求对象 (request) 详解)

想要获取请求的数据,需要通过 request 对象

js 复制代码
const server = http.createServer((req, res) => {
  // 1. 获取请求方法
  const method = req.method; // GET, POST 等
  
  // 2. 解析请求URL
  const url = new URL(req.url, `http://${req.headers.host}`);
//   URL {
//   href: 'http://localhost:3000/?a=1',
//   origin: 'http://localhost:3000',
//   protocol: 'http:',
//   username: '',
//   password: '',
//   host: 'localhost:3000',
//   hostname: 'localhost',
//   port: '3000',
//   pathname: '/',
//   search: '?a=1',
//   searchParams: URLSearchParams { 'a' => '1' },
//   hash: ''
// } url1111
  
  // 3. 获取请求路径
  const pathname = url.pathname; // 如:'/api/user'
  

  // 4. 获取查询参数
  const query = Object.fromEntries(url.searchParams);
  
  // 5. 获取请求头
  const contentType = req.headers['content-type'];
  
  // 6. 获取请求体 (POST/PUT)
  let body = '';
  req.on('data', chunk => body += chunk);
  req.on('end', () => {
    console.log('请求体内容:', body);
    
    // 设置响应
    res.end(`请求方法: ${method}, 路径: ${pathname}`);
  });
});

注意:

  • request.headers 将请求信息转化成一个对象,并将属性名都转化成了『小写』
  • 关于路径:如果访问网站的时候,只填写了 IP 地址或者是域名信息,此时请求的路径为『 / 』
  • 关于 favicon.ico:这个请求是属于浏览器自动发送的请求
js 复制代码
const http = require('http');
const server = http.createServer((req, res) => {
    // 获取请求方法和路径
    // const {method, url} = req;
    // console.log(req.url,'xxxxxxx') // /sm/api/user  http://localhost:3000/sm/api/user post
    // console.log(req.url,'xxxxxxx') // /  http://localhost:3000/ Get
    // console.log(req.url,'xxxxxxx') // /about  http://localhost:3000/about Get
  
    const { method } = req;
    const url = new URL(req.url, `http://${req.headers.host}`);
    const pathname = url.pathname;
    
    // 设置响应头
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    
    // 路由处理
    if (method === 'GET' && pathname === '/') {
      res.end('<h1>首页</h1>');
    } else if (method === 'GET' && pathname === '/about') {
      res.end('<h1>关于我们</h1>');
    } else if (method === 'POST' && pathname === '/api/user') {
      // 处理API请求...
      res.end(JSON.stringify({ code: 200, data: { name: '苏木' } }));
    } else {
      res.statusCode = 404;
      res.end('<h1>页面不存在</h1>');
    }
  });

  server.listen(3000, () => {
    console.log('服务器已启动,监听端口 3000');
  });



设置 HTTP 响应报文(响应对象 (response) 详解)
js 复制代码
const server = http.createServer((req, res) => {
  // 1. 设置状态码
  res.statusCode = 200; // 默认200,可以设置为404等
  
  // 2. 设置响应头
  res.setHeader('Content-Type', 'application/json');
  res.setHeader('Cache-Control', 'public, max-age=3600');
  
  // 3. 写入响应内容(多次写入)
  res.write('第一部分数据');
  res.write('第二部分数据');
  
  // 4. 结束响应并发送
  res.end('最后内容');
  
  // 5. 一次性写入并结束
  // res.end(JSON.stringify({ message: 'Hello' }));
});
静态文件服务

实现静态资源服务器

js 复制代码
const http = require('http');
const fs = require('fs');
const path = require('path');

// MIME 类型映射
const mimeTypes = {
  '.html': 'text/html',
  '.js': 'text/javascript',
  '.css': 'text/css',
  '.json': 'application/json',
  '.png': 'image/png',
  '.jpg': 'image/jpeg',
  '.gif': 'image/gif',
  '.svg': 'image/svg+xml',
};

const server = http.createServer((req, res) => {
  // 获取文件路径 public 文件夹下的文件的静态资源
  const filePath = path.join(__dirname, 'public', req.url);
  
  // 获取文件扩展名
  const extname = path.extname(filePath);
  
  // 设置默认内容类型
  let contentType = mimeTypes[extname] || 'application/octet-stream';
  
  // 读取文件
  fs.readFile(filePath, (err, data) => {
    if (err) {
      // 文件不存在
      if (err.code === 'ENOENT') {
        res.statusCode = 404;
        res.end('<h1>404 Not Found</h1>');
      } else {
      // 成功读取文件
      res.setHeader('Content-Type', contentType);
      res.end(data);
    }
  });
});

server.listen(9000);

// 访问: http://localhost:3000/232.png
// 结果如下
相关推荐
诗句藏于尽头3 小时前
完成ssl不安全警告
网络协议·安全·ssl
浪裡遊6 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
whale fall6 小时前
npm install安装的node_modules是什么
前端·npm·node.js
用户35218024547510 小时前
MCP极简入门:node+idea运行简单的MCP服务和MCP客户端
node.js·ai编程
-qOVOp-10 小时前
408第三季part2 - 计算机网络 - ip分布首部格式与分片
网络协议·tcp/ip·计算机网络
数通Dinner10 小时前
RSTP 拓扑收敛机制
网络·网络协议·tcp/ip·算法·信息与通信
G等你下课15 小时前
AJAX请求跨域问题
前端·javascript·http
觅_15 小时前
Node.js 的线程模型
node.js
qq_1715388517 小时前
TCP/IP协议精解:IP协议——互联网世界的邮政编码系统
网络·网络协议·tcp/ip