likes
comments
collection
share

Node.js 内置模块大揭秘:超文本传输协议(http)模块

作者站长头像
站长
· 阅读数 5

前言

大家好,今天是我们《Node.js 内置模块大揭秘》这个系列的第二篇文章,本文将深入探讨 Node.js 的 超文本传输协议(http) 模块,涵盖其基本用法、关键特性以及在实际应用中的应用场景。

其他模块可从下面了解

一、HTTP 模块基础

1.1 HTTP 模块简介

http 模块是一个核心模块,提供了创建 HTTP 服务器和客户端的功能。这个模块让 Node.js 中处理 HTTP 请求和响应变得非常简单,它采用事件驱动的方式,通过监听事件来处理请求和响应。

1.2 创建简单的 HTTP 服务器

演示一下如何使用 HTTP 模块创建一个基本的 HTTP 服务器,包括监听端口、处理请求等基本步骤。

const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello, World!\n');
});

server.listen(3000, () => {
  console.log('Server running on http://localhost:3000/');
});

1.3 处理 HTTP 请求和响应

使用 HTTP 模块处理不同类型的 HTTP 请求和生成适当的 HTTP 响应。包括解析 URL、处理查询参数等,是构建 Web 服务器的基本功能之一。

const http = require('http');
const url = require('url');
const querystring = require('querystring');

const server = http.createServer((req, res) => {
  // 解析 URL
  const parsedUrl = url.parse(req.url, true);
  
  // 获取路径和查询参数
  const path = parsedUrl.pathname;
  const query = parsedUrl.query;

  // 处理不同类型的请求
  if (req.method === 'GET' && path === '/hello') {
    handleHelloRequest(query, res);
  } else if (req.method === 'POST' && path === '/submit') {
    handlePostRequest(req, res);
  } else {
    // 处理未知路径和方法的请求
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not Found');
  }
});

// 启动服务器监听端口
server.listen(3000, () => {
  console.log('Server running on http://localhost:3000/');
});

// 处理 GET 请求
function handleHelloRequest(query, res) {
  const name = query.name || 'Guest';
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(`Hello, ${name}!\n`);
}

// 处理 POST 请求
function handlePostRequest(req, res) {
  let data = '';

  req.on('data', (chunk) => {
    // 接收 POST 数据
    data += chunk;
  });

  req.on('end', () => {
    // 解析 POST 数据
    const postData = querystring.parse(data);

    // 生成适当的响应
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end(`Received POST data: ${JSON.stringify(postData)}\n`);
  });
}

1.4 HTTP 客户端

使用 HTTP 模块创建简单的 HTTP 客户端,与其他服务器进行通信,发送请求并处理响应。

const http = require('http');

// 定义请求选项
const options = {
  hostname: 'www.example.com',
  port: 80,
  path: '/path',
  method: 'GET',
};

// 发起 HTTP 请求
const req = http.request(options, (res) => {
  let data = '';

  // 接收响应数据
  res.on('data', (chunk) => {
    data += chunk;
  });

  // 响应结束处理
  res.on('end', () => {
    console.log('Response:', data);
  });
});

// 处理请求错误
req.on('error', (error) => {
  console.error('Request error:', error.message);
});

// 结束请求
req.end();

二、HTTP 模块进阶

2.1 处理路由和请求方法

使用 HTTP 模块处理不同的路由和请求方法,实现更灵活的路由控制和处理逻辑。

const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
  // 解析请求的 URL
  const parsedUrl = url.parse(req.url, true);

  // 获取路径和查询参数
  const path = parsedUrl.pathname;
  const query = parsedUrl.query;

  // 根据不同的路径和请求方法执行不同的处理逻辑
  if (req.method === 'GET') {
    if (path === '/hello') {
      handleHelloRequest(query, res);
    } else if (path === '/goodbye') {
      handleGoodbyeRequest(res);
    } else {
      handleNotFound(res);
    }
  } else if (req.method === 'POST') {
    if (path === '/submit') {
      handlePostRequest(req, res);
    } else {
      handleNotFound(res);
    }
  } else {
    handleMethodNotAllowed(res);
  }
});

server.listen(3000, () => {
  console.log('Server running on http://localhost:3000/');
});

// 处理 GET /hello 请求
function handleHelloRequest(query, res) {
  const name = query.name || 'Guest';
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(`Hello, ${name}!\n`);
}

// 处理 GET /goodbye 请求
function handleGoodbyeRequest(res) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Goodbye!\n');
}

// 处理 POST /submit 请求
function handlePostRequest(req, res) {
  let data = '';

  req.on('data', (chunk) => {
    // 接收 POST 数据
    data += chunk;
  });

  req.on('end', () => {
    // 解析 POST 数据
    const postData = JSON.parse(data);

    // 生成适当的响应
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(postData));
  });
}

// 处理未找到的路径
function handleNotFound(res) {
  res.writeHead(404, { 'Content-Type': 'text/plain' });
  res.end('Not Found\n');
}

// 处理不允许的请求方法
function handleMethodNotAllowed(res) {
  res.writeHead(405, { 'Content-Type': 'text/plain' });
  res.end('Method Not Allowed\n');
}

2.2 中间件的概念与应用

中间件是一种在请求和响应处理过程中执行的函数,用于对 HTTP 请求和响应进行预处理、增强或修改。中间件可以在请求到达路由处理之前、路由处理过程中或在响应被发送给客户端之前执行。

Node.js 中,Express 框架就是一个常见的使用中间件的例子。

使用 HTTP 模块实现和应用中间件,提高代码的可维护性和扩展性。

const http = require('http');
const url = require('url');

// 定义中间件
function loggerMiddleware(req, res, next) {
  console.log(`[${new Date().toLocaleString()}] ${req.method} ${req.url}`);
  next(); // 调用下一个中间件或路由处理
}

function helloMiddleware(req, res, next) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello, Middleware!\n');
}

// 创建 HTTP 服务器
const server = http.createServer((req, res) => {
  // 解析请求的 URL
  const parsedUrl = url.parse(req.url, true);

  // 使用中间件
  loggerMiddleware(req, res, () => {
    helloMiddleware(req, res, () => {
      // 其他路由或中间件
      res.writeHead(404, { 'Content-Type': 'text/plain' });
      res.end('Not Found\n');
    });
  });
});

server.listen(3000, () => {
  console.log('Server running on http://localhost:3000/');
});

2.3 处理文件上传

在 Node.js 中,使用 http 模块处理文件上传通常涉及到解析请求体中的文件数据、存储文件等操作。

我们演示一下如何使用 HTTP 模块处理文件上传,包括解析文件、存储文件等操作。

以下是一个使用 http 模块处理文件上传的基本示例,其中我们还将使用 formidable 模块来处理文件上传的部分:

首先,确保已经安装 formidable 模块:

npm install formidable

然后,创建一个 Node.js 服务器文件(例如 app.js):

const http = require('http');
const formidable = require('formidable');
const fs = require('fs');

const server = http.createServer((req, res) => {
  if (req.url === '/upload' && req.method.toLowerCase() === 'post') {
    // 创建 formidable 表单解析器
    const form = new formidable.IncomingForm();

    // 指定上传文件保存的目录
    form.uploadDir = __dirname + '/uploads';

    // 保留文件的扩展名
    form.keepExtensions = true;

    // 解析表单数据
    form.parse(req, (err, fields, files) => {
      if (err) {
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('Internal Server Error');
        return;
      }

      // 获取上传的文件信息
      const { name, path, size } = files.file;

      // 生成新的文件名,也可以根据需要进行其他处理
      const newFileName = Date.now() + '_' + name;

      // 将文件移动到指定目录并重命名
      fs.rename(path, form.uploadDir + '/' + newFileName, (err) => {
        if (err) {
          res.writeHead(500, { 'Content-Type': 'text/plain' });
          res.end('Internal Server Error');
          return;
        }

        // 文件上传成功,返回客户端相应信息
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end(`File ${newFileName} uploaded successfully!`);
      });
    });

    return;
  }

  // 处理其他请求...
  res.writeHead(404, { 'Content-Type': 'text/plain' });
  res.end('Not Found');
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}/`);
});

这段代码很长,不过实际上就是我们创建了一个简单的 HTTP 服务器,监听在 http://localhost:3000/。当客户端发送 POST 请求到 /upload 路径时,服务器将使用 formidable 模块解析请求体中的文件数据,并保存到指定目录(在这里就是 ./uploads)。处理完成后,服务器返回相应信息。

一般我们会在运行该服务器之前创建 ./uploads 目录,用于保存上传的文件。

2.4 安全性和性能优化

另外,我们可以通过 HTTP 模块提高应用的安全性、防范常见攻击,并进行性能优化

2.4.1 安全性提升

  1. 使用 HTTPS

    • 通过使用 HTTPS 加密传输数据,可以防止中间人攻击,确保数据的机密性和完整性。
  2. 数据验证和过滤

    • 在服务器端对用户输入的数据进行严格的验证和过滤,以防止 SQL 注入、XSS(跨站脚本攻击)等攻击。
  3. 防止 CSRF 攻击

    • 使用 CSRF Token 来验证请求的合法性,确保请求是由合法用户发起的。
  4. 设置适当的跨域策略

    • 使用 CORS(跨源资源共享)设置适当的跨域策略,避免不必要的跨域风险。
  5. HTTP 头安全设置

    • 使用 HTTP 头来增强安全性,如设置 Content Security Policy(CSP)头,限制资源加载的来源,防止恶意脚本的注入。
  6. 防止点击劫持

    • 使用 X-Frame-Options 头来防止网页被嵌套到其他网页中,避免点击劫持攻击。
  7. 保护敏感信息

    • 不要将敏感信息存储在客户端,确保敏感信息通过安全的方式传输和存储。

2.4.2 防范常见攻击

  1. SQL 注入防护

    • 使用参数化查询或预编译语句,避免直接拼接用户输入到 SQL 查询中,以防止 SQL 注入攻击。
  2. XSS 防护

    • 对用户输入进行 HTML 转义或使用现代前端框架提供的 XSS 防护机制,确保用户输入不会被解析为恶意脚本。
  3. CSRF 防护

    • 使用 CSRF Token 来验证请求的合法性,确保请求是由合法用户发起的。
  4. 文件上传安全

    • 限制文件上传的类型和大小,确保文件上传的过程中不会导致安全问题。

2.4.3 性能优化

  1. 使用 CDN

    • 使用内容分发网络(CDN)来加速静态资源的传输,提高网页加载速度。
  2. 启用压缩

    • 启用服务器端的压缩功能,减小传输数据的大小,提高加载速度。
  3. 异步加载

    • 将页面中的非关键性资源(如统计脚本、广告)异步加载,避免阻塞主要内容的加载。
  4. 缓存策略

    • 使用适当的缓存策略,包括浏览器缓存、服务器缓存等,减少重复加载相同资源的次数。
  5. 减少 HTTP 请求数量

    • 合并和精简文件,减少 HTTP 请求的数量,加速页面加载。
  6. 使用懒加载和延迟加载

    • 对于大型页面,使用懒加载和延迟加载来分阶段加载资源,提高页面的渲染速度。
  7. 使用 Web Workers

    • 将一些计算密集型的任务交给 Web Workers 处理,避免阻塞主线程。
  8. 优化图片

    • 使用适当的图片格式、压缩图片,以及懒加载图片,减小页面的图片资源加载开销。

三、实际应用与实践

3.1 构建 RESTful API

我们以 Express.js 为例,演示如何构建 RESTful API,包括资源的增删改查操作。

首先,确保已经安装了 Node.js 和 npm(Node.js 包管理器)。然后,我们通过以下步骤创建一个简单的 RESTful API:

  1. 初始化项目: 在你的项目文件夹中,打开命令行,运行以下命令初始化一个 Node.js 项目,并安装 Express:

    npm init -y
    npm install express
    
  2. 创建主文件(如 app.js): 创建一个主文件,例如 app.js,并在其中编写以下代码:

    const express = require('express');
    const app = express();
    const port = 3000;
    
    // 允许解析 JSON 数据
    app.use(express.json());
    
    // 示例数据
    let resources = [
      { id: 1, name: 'Resource 1' },
      { id: 2, name: 'Resource 2' }
    ];
    
    // 获取所有资源
    app.get('/resources', (req, res) => {
      res.json(resources);
    });
    
    // 获取单个资源
    app.get('/resources/:id', (req, res) => {
      const id = parseInt(req.params.id);
      const resource = resources.find(r => r.id === id);
    
      if (resource) {
        res.json(resource);
      } else {
        res.status(404).json({ message: 'Resource not found' });
      }
    });
    
    // 创建新资源
    app.post('/resources', (req, res) => {
      const newResource = req.body;
      resources.push(newResource);
      res.status(201).json(newResource);
    });
    
    // 更新资源
    app.put('/resources/:id', (req, res) => {
      const id = parseInt(req.params.id);
      const updatedResource = req.body;
    
      resources = resources.map(r => (r.id === id ? updatedResource : r));
    
      res.json(updatedResource);
    });
    
    // 删除资源
    app.delete('/resources/:id', (req, res) => {
      const id = parseInt(req.params.id);
      resources = resources.filter(r => r.id !== id);
      res.status(204).end();
    });
    
    // 启动服务器
    app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });
    

我们创建了一个简单的 Express 应用,定义了四个路由分别用于获取所有资源、获取单个资源、创建新资源以及更新和删除资源。数据存储在内存中,实际项目中我们可能需要使用数据库。

  1. 运行应用: 在命令行中运行以下命令启动应用:

    node app.js
    

    你的应用将在 http://localhost:3000 上运行。

  2. 测试 API: 使用工具如 Postman 或 cURL 来测试我们的 RESTful API。可以发送 GET、POST、PUT 和 DELETE 请求,分别测试获取资源、创建新资源、更新资源和删除资源的功能。

3.2 WebSocket 通信

在 Node.js 中,你可以使用 http 模块结合 websocket 模块或其他 WebSocket 库来实现 WebSocket 通信。

这里我们使用 http 模块和 websocket 模块实现实时双向通信。

首先,安装 websocket 模块。如果没有安装,可以通过以下命令进行安装:

npm install websocket

接下来,创建一个简单的 WebSocket 服务器:

const http = require('http');
const WebSocket = require('websocket').server;

// 创建 HTTP 服务器
const server = http.createServer((request, response) => {
  response.writeHead(404);
  response.end();
});

// 创建 WebSocket 服务器
const wsServer = new WebSocket({
  httpServer: server,
});

// 监听 WebSocket 连接
wsServer.on('request', (request) => {
  const connection = request.accept(null, request.origin);
  
  // 发送欢迎消息给客户端
  connection.sendUTF('Welcome to the WebSocket server!');

  // 监听客户端消息
  connection.on('message', (message) => {
    if (message.type === 'utf8') {
      console.log(`Received Message: ${message.utf8Data}`);
      
      // 原样返回消息给客户端
      connection.sendUTF(`You said: ${message.utf8Data}`);
    }
  });

  // 监听连接关闭
  connection.on('close', (reasonCode, description) => {
    console.log(`Connection closed: ${reasonCode} - ${description}`);
  });
});

// 启动 HTTP 服务器
const port = 8080;
server.listen(port, () => {
  console.log(`Server is listening on http://localhost:${port}`);
});

我们可以使用浏览器或其他 WebSocket 客户端连接到 ws://localhost:8080,发送消息并观察控制台输出。

3.3 与 Express 框架结合使用

另外,我们可以将 HTTP 模块与 Express 框架结合使用,借助 Express 的功能简化开发流程。

Express 是一个流行的 Node.js Web 框架,它提供了一套简单而灵活的工具,可以轻松地构建 Web 应用程序和 RESTful API。如果你想将 HTTP 模块与 Express 框架结合使用,以下是一些建议:

  1. 安装 Express: 在项目目录下执行以下命令安装 Express:

    npm install express
    
  2. 创建 Express 应用: 在你的项目中,创建一个新的文件(例如 app.js)并编写以下代码:

    const express = require('express');
    const app = express();
    const port = 3000;
    
    // 定义一个简单的路由
    app.get('/', (req, res) => {
      res.send('Hello, Express!');
    });
    
    // 启动服务器
    app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });
    

    在上面的例子中,我们使用 express 模块创建了一个 Express 应用,并定义了一个简单的路由,当访问根路径时返回 "Hello, Express!"。

  3. 结合 HTTP 模块: 如果你需要更底层的控制,可以结合使用 http 模块。例如,你可以将 Express 应用嵌套在一个 http 服务器中:

    const http = require('http');
    const express = require('express');
    const app = express();
    const port = 3000;
    
    app.get('/', (req, res) => {
      res.send('Hello, Express!');
    });
    
    // 创建 HTTP 服务器并将 Express 应用嵌套在其中
    const server = http.createServer(app);
    
    // 启动服务器
    server.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });
    

    这样,你可以使用 http 模块创建更多的配置选项,如启用 HTTPS,使用不同的网络接口等。

  4. 使用 Express 中间件: Express 的强大之处在于它的中间件系统。你可以使用各种中间件来处理请求、实现路由、处理错误等。例如,使用 body-parser 中间件来解析 POST 请求的请求体:

    npm install body-parser
    
    const express = require('express');
    const bodyParser = require('body-parser');
    const app = express();
    const port = 3000;
    
    // 使用 body-parser 中间件解析 POST 请求的请求体
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    
    // 处理 POST 请求
    app.post('/post-endpoint', (req, res) => {
      const data = req.body;
      res.json({ receivedData: data });
    });
    
    // 启动服务器
    app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });
    

    这里我们使用 body-parser 中间件来解析 JSON 和表单数据。

通过结合使用 Express 和 HTTP 模块可以更灵活地控制应用程序的配置和行为。

Express 提供了一组强大而简单的工具,用于处理路由、中间件、请求和响应等,从而简化 Web 应用程序的开发流程。

3.4 部署和监控

将 Node.js HTTP 服务器部署到生产环境这个过程涉及一系列步骤,包括性能优化、安全性考虑、进程管理、监控和日志记录等。

3.4.1 部署步骤

  1. 使用进程管理工具:

    • 在生产环境中,推荐使用进程管理工具如 PM2 或 Forever 来管理 Node.js 进程。这些工具可以确保你的应用在崩溃或异常退出时能够自动重启。

      # 安装 PM2
      npm install pm2 -g
      
      # 启动应用
      pm2 start app.js
      
      # 查看应用状态
      pm2 status
      
  2. 使用反向代理:

    • 将 Node.js 服务器放在反向代理(例如 Nginx 或 Apache)之后,可以提高性能、实现负载均衡和提供安全性。
  3. 使用环境变量:

    • 在生产环境中,使用环境变量来配置敏感信息(如数据库连接字符串、API 密钥等),而不要硬编码在代码中。
  4. 启用 HTTPS:

    • 使用 Let's Encrypt 等工具获取免费 SSL 证书,启用 HTTPS 以确保数据传输的安全性。

3.4.2 监控和日志记录

  1. 使用应用性能监控工具:

    • 使用应用性能监控(APM)工具来追踪应用程序的性能指标、错误和异常。一些流行的 APM 工具包括 New Relic、AppDynamics 和 Datadog。
  2. 集中式日志记录:

    • 将应用程序日志记录到集中式日志系统,方便跟踪问题和进行分析。ELK Stack(Elasticsearch、Logstash、Kibana)、Papertrail 和 Splunk 是一些常见的集中式日志记录解决方案。
  3. 使用监控工具:

    • 使用监控工具(如 Prometheus、Grafana)来监控系统资源使用情况、网络流量和应用程序性能。这有助于提前发现并解决潜在的问题。
  4. 错误追踪:

    • 集成错误追踪工具(如 Sentry、Rollbar)以实时监控和报告应用程序中的错误,帮助你快速诊断和修复问题。

3.4.3 安全性考虑

  1. 安全头部:

    • 在 HTTP 响应头中使用适当的安全头部,如 Strict-Transport-Security、Content-Security-Policy 等。
  2. 防止 DoS 攻击:

    • 使用工具如 Cloudflare、Rate Limiter 中间件等来防止拒绝服务(DoS)攻击。
  3. 定期更新依赖:

    • 定期检查和更新应用程序的依赖项,以确保使用最新且安全的库版本。
  4. 保护敏感信息:

    • 不要在代码中硬编码敏感信息,使用环境变量,并使用专业的安全性工具和最佳实践来保护敏感信息。
  5. 审计代码:

    • 定期审查和审计代码,确保没有潜在的安全漏洞。

四、 http 模块中十个较为常用的函数方法

在Node.js http 模块中,有很多函数和方法可供我们使用。以下是我总结的十个较为常用而重要的函数方法:

1. createServer(requestListener)

描述: 创建一个 HTTP 服务器实例,并指定一个回调函数来处理每个传入的请求。

参数:

  • requestListener:一个函数,用于处理请求的回调函数,接收 requestresponse 两个参数。

示例:

const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello, World!\n');
});

server.listen(3000, () => {
  console.log('Server running on http://localhost:3000/');
});

2. listen(port, [hostname], [backlog], [callback])

描述: 启动服务器监听指定的端口和主机名。

参数:

  • port:要监听的端口号。
  • [hostname]:可选,要监听的主机名,默认为 'localhost'
  • [backlog]:可选,指定等待队列的最大长度。
  • [callback]:可选,服务器启动后的回调函数。

示例:

server.listen(3000, 'localhost', () => {
  console.log('Server is listening on port 3000');
});

3. request 事件

描述: 当客户端发起请求时触发的事件。事件回调函数接收 requestresponse 两个参数。

示例:

server.on('request', (req, res) => {
  // 处理请求
});

4. response 对象

描述: 表示服务器对客户端请求的响应,通过这个对象设置响应头和发送响应体。

示例:

res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<html><body>Hello, World!</body></html>');

5. req.url 属性

描述: 获取客户端请求的 URL。

示例:

const url = req.url;
console.log(`Requested URL: ${url}`);

6. req.method 属性

描述: 获取客户端请求的 HTTP 方法(GET、POST 等)。

示例:

const method = req.method;
console.log(`Request method: ${method}`);

7. writeHead(statusCode, [headers]) 方法

描述: 设置响应头的状态码和可选的响应头。

示例:

res.writeHead(404, { 'Content-Type': 'text/plain' });

8. end([data], [encoding], [callback]) 方法

描述: 结束响应过程,可选地发送最后一块数据。

示例:

res.end('Hello, World!\n');

9. URL 解析

描述: 使用 url.parse() 解析 URL。

示例:

const url = require('url');
const parsedUrl = url.parse(req.url, true);
console.log(parsedUrl);

10. 查询字符串解析

描述: 使用 querystring.parse() 解析查询字符串。

示例:

const querystring = require('querystring');
const params = querystring.parse(parsedUrl.query);
console.log(params);

通常,在使用这些功能之前,需要先引入 Node.js 的 http 模块,以便创建 HTTP 服务器。

// 引入 http 模块
const http = require('http');

// 创建一个 HTTP 服务器
const server = http.createServer((req, res) => {
  // 处理请求的逻辑
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello, World!\n');
});

// 服务器监听指定的端口和主机名
server.listen(3000, 'localhost', () => {
  console.log('Server is listening on port 3000');
});

// 处理 request 事件
server.on('request', (req, res) => {
  // 处理请求的逻辑
});

// 其他相关概念和方法的使用

结语

今天的分享就到这了,任何问题欢迎大家在评论区指出~