You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express服务器返回循环结构转JSON错误的原因与解决

Express服务器返回"Converting circular structure to JSON"错误的原因与修复方案

问题场景

我是NodeJS新手,搭建了如下Express服务器:

const expressJS = require("express");

const server = expressJS();

server.listen("3333", () => console.log("Server started on Port 3333"));

server.get("/", (request, response) => {
    const req = request;
    response.send(req)
});

访问http://localhost:3333/时,服务器返回如下错误:

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Socket'
    |     property 'parser' -> object with constructor 'HTTPParser'
    --- property 'socket' closes the circle
    at JSON.stringify (<anonymous>)
    at stringify (f:\NodeJS\REST_API\node_modules\express\lib\response.js:1150:12)
    at ServerResponse.json (f:\NodeJS\REST_API\node_modules\express\lib\response.js:271:14)
    at ServerResponse.send (f:\NodeJS\REST_API\node_modules\express\lib\response.js:162:21)
    at f:\NodeJS\REST_API\server.js:11:14
    at Layer.handle [as handle_request] (f:\NodeJS\REST_API\node_modules\express\lib\router\layer.js:95:5)
    at next (f:\NodeJS\REST_API\node_modules\express\lib\router\route.js:144:13)
    at Route.dispatch (f:\NodeJS\REST_API\node_modules\express\lib\router\route.js:114:3)
    at Layer.handle [as handle_request] (f:\NodeJS\REST_API\node_modules\express\lib\router\layer.js:95:5)
    at f:\NodeJS\REST_API\node_modules\express\lib\router\index.js:284:15

1. 错误的根本原因

  • Express的response.send()方法在传入对象时,会自动调用JSON.stringify()将对象转为JSON字符串返回给客户端。
  • request是一个包含循环引用的复杂对象(比如Socket和HTTPParser互相引用),而JSON.stringify()无法处理循环引用结构,因此抛出该错误。

2. 修复方案

根据需求,推荐以下几种修复方式:

方式一:返回request对象的指定属性

如果只需要请求中的部分信息,直接提取对应属性返回即可,这是最常用的方案:

server.get("/", (request, response) => {
    // 返回客户端需要的核心请求信息
    response.send({
        url: request.url,
        method: request.method,
        clientIp: request.ip,
        headers: request.headers
    });
});

方式二:调试时查看完整request对象(仅用于开发环境)

如果需要调试查看整个request对象的内容,可以用Node内置的util.inspect()将其转为字符串返回:

const util = require('util');

server.get("/", (request, response) => {
    // depth: null 表示展开所有层级的属性
    response.send(util.inspect(request, { depth: null }));
});

最佳实践

  • 禁止直接返回整个request或response对象,它们包含大量服务端内部信息(如Socket连接、中间件上下文),不仅会引发循环引用错误,还可能泄露敏感数据。
  • 接口仅返回客户端需要的必要数据,保持响应体简洁,提升传输性能。
  • 开发调试时,优先在服务端用console.log(util.inspect(request, { depth: null }))打印请求信息,而非返回给客户端。

内容的提问来源于stack exchange,提问作者Angular animal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 07:27:24