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 包处理跨域,并添加请求验证和错误捕获。
相关推荐
你想考研啊2 天前
win11卸载sql server express版本
express
克里斯蒂亚诺更新4 天前
vue展示node express调用python解析tdms
服务器·python·express
小天源9 天前
Oracle Database 11g Express Edition (XE) 11.2.0.2 在离线银河麒麟 V10 上的部署手册
数据库·oracle·express·麒麟v10·oracle11g·oracle-xe-11g
C++实习生13 天前
Visual Studio Express 2015 for Windows Desktop 中文学习版
windows·express·visual studio
C++实习生13 天前
Visual C++ 2005 Express 中文版
express·c++20
张彦峰ZYF14 天前
QLExpress 字符串能力解析:机制、用法与工程实践
字符串·express·qlexpress规则表达力
biyezuopinvip14 天前
基于uni-app和Express的问答对战小程序的设计与实现(论文)
小程序·uni-app·毕业设计·论文·express·毕业论文·问答对战小程序的设计与实现
天意pt14 天前
Idempotency 幂等性 - 点赞和投票功能
前端·javascript·express
水冗水孚21 天前
告别黑盒!手写Windows版简易NodeMON,学习文件监听代码修改与进程服务重启知识
node.js·express
天意pt21 天前
Blog-SSR 系统操作手册(v1.0.0)
前端·vue.js·redis·mysql·docker·node.js·express