express.text和fetch配合使用深入全面教程

一、核心概念先理清

1. express.text() 是什么?

express.text() 是 Express 框架内置的中间件 ,用于解析 HTTP 请求体中 Content-Typetext/plain 格式的数据,解析后会将数据挂载到 req.body 上,方便后续路由处理。

  • 核心作用:处理纯文本格式的请求体(区别于 express.json() 处理 JSON、express.urlencoded() 处理表单)
  • 默认配置:charset: 'utf-8'type: 'text/plain',支持自定义扩展

2. fetch() 是什么?

fetch() 是浏览器/Node.js(v18+ 内置)提供的原生 API,用于发送 HTTP 请求,替代传统的 XMLHttpRequest,返回 Promise 对象,支持异步处理请求/响应。

  • 发送纯文本请求时,需手动配置 Content-Type: text/plain,并将请求体传入纯文本字符串

二、前置准备

  1. 初始化项目(后端)
bash 复制代码
# 创建项目文件夹
mkdir express-fetch-text-demo && cd express-fetch-text-demo
# 初始化 npm
npm init -y
# 安装 express
npm install express
  1. 环境说明
  • 后端:Node.js ≥ 14、Express ≥ 4.16+(express.text() 从 Express 4.16 开始内置)
  • 前端:现代浏览器(支持 fetch())或 Node.js ≥ 18(内置 fetch()

三、完整实战示例

示例1:基础用法(前端浏览器 ↔ Express 后端)

步骤1:搭建 Express 后端(解析纯文本请求)

创建 server.js,配置 express.text() 并编写路由:

javascript 复制代码
// server.js
const express = require('express');
const app = express();
const port = 3000;

// 配置 express.text() 中间件(全局生效,所有路由均可解析 text/plain 请求体)
// 可自定义配置:比如修改默认编码、扩展支持的 Content-Type
app.text({
  charset: 'utf-8', // 编码格式,默认 utf-8
  type: 'text/plain' // 匹配的 Content-Type,可写数组如 ['text/plain', 'text/custom']
});

// 解决跨域(前端浏览器请求必备,否则会报 CORS 错误)
app.use((req, res, next) => {
  // 允许所有前端域名访问(生产环境需指定具体域名,如 http://localhost:5500)
  res.setHeader('Access-Control-Allow-Origin', '*');
  // 允许的请求方法
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  // 允许的请求头
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

// 1. 接收纯文本请求(POST 方法,推荐用于提交数据)
app.post('/api/receive-text', (req, res) => {
  try {
    // req.body 即为 express.text() 解析后的纯文本内容
    const receivedText = req.body;
    console.log('收到纯文本数据:', receivedText);

    // 响应给前端(可返回纯文本或 JSON,这里演示返回纯文本)
    res.setHeader('Content-Type', 'text/plain');
    res.send(`后端已接收你的文本:${receivedText}`);
  } catch (error) {
    res.status(500).send('服务器解析文本失败:' + error.message);
  }
});

// 2. 启动服务器
app.listen(port, () => {
  console.log(`后端服务器运行在 http://localhost:${port}`);
});
步骤2:搭建前端页面(用 fetch() 发送纯文本)

创建 index.html,放在任意文件夹(用 VS Code Live Server 启动,默认端口 5500):

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>fetch + express.text() 示例</title>
  <style>
    .container { margin: 20px; }
    textarea { width: 300px; height: 100px; margin-bottom: 10px; }
    button { padding: 8px 16px; cursor: pointer; }
    #response { margin-top: 10px; color: #333; }
  </style>
</head>
<body>
  <div class="container">
    <h3>输入纯文本发送给后端</h3>
    <textarea id="textInput" placeholder="请输入任意纯文本..."></textarea>
    <br>
    <button id="sendBtn">发送文本</button>
    <div id="response"></div>
  </div>

  <script>
    // 1. 获取 DOM 元素
    const textInput = document.getElementById('textInput');
    const sendBtn = document.getElementById('sendBtn');
    const responseDiv = document.getElementById('response');

    // 2. 发送纯文本的核心逻辑(fetch 配置)
    async function sendTextToServer() {
      const textContent = textInput.value.trim();
      if (!textContent) {
        alert('请输入要发送的文本!');
        return;
      }

      try {
        // fetch(url, options)
        const response = await fetch('http://localhost:3000/api/receive-text', {
          method: 'POST', // 对应后端的 POST 路由
          headers: {
            // 关键:指定请求体格式为 text/plain(与 express.text() 对应)
            'Content-Type': 'text/plain; charset=utf-8'
          },
          body: textContent // 直接传入纯文本字符串(无需 JSON.stringify)
        });

        // 处理后端响应(后端返回的是 text/plain,用 response.text() 解析)
        const responseText = await response.text();
        responseDiv.textContent = '后端响应:' + responseText;
      } catch (error) {
        responseDiv.textContent = '请求失败:' + error.message;
        responseDiv.style.color = 'red';
      }
    }

    // 3. 绑定按钮点击事件
    sendBtn.addEventListener('click', sendTextToServer);
  </script>
</body>
</html>
步骤3:运行测试
  1. 启动后端:node server.js,看到提示 后端服务器运行在 http://localhost:3000
  2. 启动前端:用 VS Code Live Server 打开 index.html,访问 http://localhost:5500
  3. 测试操作:
    • 在文本框输入任意内容(如「Hello Express + Fetch!」)
    • 点击「发送文本」,前端会显示后端响应
    • 后端终端会打印「收到纯文本数据:Hello Express + Fetch!」

示例2:Node.js 端用 fetch() 发送纯文本(无浏览器跨域)

如果你的客户端也是 Node.js 程序(v18+),无需处理 CORS,直接发送请求:

创建 node-client.js

javascript 复制代码
// node-client.js
async function sendText() {
  const textContent = '这是 Node.js 客户端发送的纯文本';

  try {
    const response = await fetch('http://localhost:3000/api/receive-text', {
      method: 'POST',
      headers: {
        'Content-Type': 'text/plain'
      },
      body: textContent
    });

    const responseText = await response.text();
    console.log('后端响应:', responseText);
  } catch (error) {
    console.error('请求失败:', error);
  }
}

// 执行发送
sendText();

运行测试:

  1. 确保后端 server.js 已启动
  2. 执行客户端:node node-client.js
  3. 终端会输出后端响应,同时后端终端打印接收的文本

四、高级配置与注意事项

1. express.text() 高级配置

javascript 复制代码
// 自定义配置示例
app.text({
  charset: 'gbk', // 适配中文老式编码(需确保前端发送时编码一致)
  type: ['text/plain', 'text/custom', 'application/x-text'], // 扩展支持的 Content-Type
  limit: '10kb' // 限制请求体大小,默认 100kb,超出会报错
});

2. fetch() 发送纯文本的关键配置

配置项 必选/可选 说明
method 必选 需与后端路由一致(推荐 POST/PUT/DELETEGET 无请求体,无需解析)
headers.Content-Type 必选 必须设为 text/plain(或 express.text() 配置的扩展类型),否则后端无法解析
body 必选 直接传入纯文本字符串(无需序列化,与 JSON.stringify 区分)
credentials 可选 若需要携带 Cookie(如登录状态),设为 include(浏览器端跨域时需后端配合)

3. 响应处理的对应方式

后端返回不同格式,前端需用对应的解析方法:

后端响应 Content-Type 前端解析方法
text/plain response.text()
application/json response.json()
blob(文件) response.blob()

示例:后端返回 JSON,前端解析

javascript 复制代码
// 后端路由
app.post('/api/receive-text-json', (req, res) => {
  res.json({
    code: 200,
    msg: '接收成功',
    data: req.body
  });
});

// 前端 fetch 解析
const response = await fetch('http://localhost:3000/api/receive-text-json', { /* 配置同上 */ });
const responseData = await response.json(); // 用 json() 解析
console.log(responseData.data); // 拿到纯文本内容

4. 常见问题排查

问题1:req.bodyundefined
  • 原因1:未配置 express.text() 中间件(或配置在路由之后,中间件未生效)
  • 原因2:前端 Content-Type 配置错误(如写成 application/json
  • 原因3:请求方法为 GET(GET 无请求体,req.body 始终为 undefined
  • 解决方案:确保 app.text() 在路由之前配置,前端 Content-Type 与后端匹配,使用 POST/PUT 方法
问题2:跨域报错(Access-Control-Allow-Origin)
  • 原因:浏览器同源策略限制,前端域名与后端不一致
  • 解决方案:
    1. 后端添加 CORS 中间件(如示例1中的自定义 CORS,或使用 cors 包)
    2. 生产环境避免 *,指定具体前端域名:res.setHeader('Access-Control-Allow-Origin', 'http://xxx.com')
    3. 可选:使用代理(如 Vite 代理、Nginx 反向代理)
问题3:中文乱码
  • 原因:前后端编码不一致(如后端 charset: 'gbk',前端用 utf-8
  • 解决方案:
    1. 统一使用 utf-8 编码(推荐)
    2. 前端发送时指定编码:'Content-Type': 'text/plain; charset=gbk'
    3. 后端解析时对应配置 charset: 'gbk'
问题4:请求体过大报错
  • 原因:express.text() 默认限制 100kb,超出会返回 413 错误
  • 解决方案:自定义 limit 配置,如 app.text({ limit: '1mb' })

五、生产环境最佳实践

  1. 避免全局 app.text() :若只有部分路由需要解析纯文本,可将中间件配置在单个路由上:

    javascript 复制代码
    // 仅该路由生效
    app.post('/api/only-text', express.text(), (req, res) => {
      // 处理逻辑
    });
  2. 使用 cors 包替代自定义 CORS :生产环境更稳定:

    bash 复制代码
    npm install cors
    javascript 复制代码
    const cors = require('cors');
    // 全局启用
    app.use(cors({
      origin: 'http://your-frontend.com', // 指定前端域名
      credentials: true // 允许携带 Cookie
    }));
  3. 添加请求验证 :解析后验证 req.body 是否合法,避免空数据:

    javascript 复制代码
    app.post('/api/receive-text', (req, res) => {
      if (!req.body || req.body.length === 0) {
        return res.status(400).send('请传入有效的纯文本数据');
      }
      // 后续逻辑
    });
  4. 错误捕获 :使用 try/catch 包裹解析逻辑,或全局错误处理中间件:

    javascript 复制代码
    // 全局错误处理
    app.use((err, req, res, next) => {
      console.error('服务器错误:', err.stack);
      res.status(500).send('服务器内部错误');
    });

总结

  1. express.text() 专用于解析 text/plain 格式请求体,解析后数据挂载在 req.body,需配置在路由之前。
  2. fetch() 发送纯文本时,必须指定 headers: { 'Content-Type': 'text/plain' },且 body 直接传入字符串。
  3. 浏览器端需处理 CORS 跨域,前后端编码需统一,避免中文乱码和 req.bodyundefined 的问题。
  4. 生产环境建议按需使用 express.text()、用 cors 包处理跨域,并添加请求验证和错误捕获。
相关推荐
GDAL2 小时前
Express 中 CORS 跨域问题解决教程
express·cors
GDAL1 天前
Express POST 请求深入全面讲解教程
express
正经教主2 天前
【Trae+AI】和Trae学习搭建App_2.1:第3章·手搓后端基础框架Express
人工智能·后端·学习·express
你真的可爱呀5 天前
2.Express 核心语法与路由
中间件·node.js·express
骚团长5 天前
SQL server 配置管理器-SQL server 服务-远程过程调试失败 [0x800706be]-(Express LocalDB卸载掉)完美解决!
java·服务器·express
你真的可爱呀6 天前
1.基础环境搭建与核心认知
node.js·express
你真的可爱呀6 天前
3.MySQL 数据库集成
mysql·node.js·express
你真的可爱呀6 天前
4.前后端联调(Vue3+Vite + Express + MySQL)
mysql·node.js·vue·express
正经教主7 天前
【Trae+AI】和Trae学习搭建App_2.2.1:第4章·安卓APP调用Express后端实战1:前端调用后端
人工智能·学习·express