TypeError: 在 nodejs 中将循环结构转换为 JSON

我正在使用 node.js 的请求包

密码:

 var formData = ({first_name:firstname,last_name:lastname,user_name:username, email:email,password:password});


request.post({url:'http://localhost:8081/register', JSON: formData}, function(err, connection, body) {


exports.Register = function(req, res) {
res.header("Access-Control-Allow-Origin", "*");
console.log("Request data " +JSON.stringify(req));

我得到了这个错误:

TypeError: 将循环结构转换为 JSON

有人能告诉我出了什么问题吗

261866 次浏览

JSON doesn't accept circular objects - objects which reference themselves. JSON.stringify() will throw an error if it comes across one of these.

The request (req) object is circular by nature - Node does that.

In this case, because you just need to log it to the console, you can use the console's native stringifying and avoid using JSON:

console.log("Request data:");
console.log(req);

Try using this npm package. This helped me decoding the res structure from my node while using passport-azure-ad for integrating login using Microsoft account

https://www.npmjs.com/package/circular-json

You can stringify your circular structure by doing:

const str = CircularJSON.stringify(obj);

then you can convert it onto JSON using JSON parser

JSON.parse(str)

TypeError: Converting circular structure to JSON in nodejs: This error can be seen on Arangodb when using it with Node.js, because storage is missing in your database. If the archive is created under your database, check in the Aurangobi web interface.

I also ran into this issue. It was because I forgot to await for a promise.

use this https://www.npmjs.com/package/json-stringify-safe

var stringify = require('json-stringify-safe');
var circularObj = {};
circularObj.circularRef = circularObj;
circularObj.list = [ circularObj, circularObj ];
console.log(stringify(circularObj, null, 2));




stringify(obj, serializer, indent, decycler)

I came across this issue when not using async/await on a asynchronous function (api call). Hence adding them / using the promise handlers properly cleared the error.

Came across this issue in my Node Api call when I missed to use await keyword in a async method in front of call returning Promise. I solved it by adding await keyword.

It's because you don't an async response For example:

app.get(`${api}/users`, async (req, res) => {
const users = await User.find()
res.send(users);
})

If you are sending reponse , Just use await before response

await res.json({data: req.data});

This is because JavaScript structures that include circular references can't be serialized with a"plain" JSON.stringify.

https://www.npmjs.com/package/circular-json mentioned by @Dinesh is a good solution. But this npm package has been deprecated.

So use https://www.npmjs.com/package/flatted npm package directly from the creator of CircularJSON.

Simple usage. In your case, code as follows

import package

// ESM
import {parse, stringify} from 'flatted';


// CJS
const {parse, stringify} = require('flatted');

and

console.log("Request data " + stringify(req));

I forgotten to use await keyword in async function. with the given systax

blogRouter.put('/:id', async (request, response) => {
const updatedBlog = Blog.findByIdAndUpdate(
request.params.id,
request.body,
{ new: true }
);
response.status(201).json(updatedBlog);
});

Blog.findByIdAndUpdate should be used with the await keyword.

Try this as well

console.log(JSON.parse(JSON.stringify(req.body)));

I was able to get the values using this method, found at careerkarma.com

Output looks like this. Preview of the output

I just run this code in the debugger console. Pass your object to this function.
Copy paste the function also.

 const replacerFunc = () => {
const visited = new WeakSet();
return (key, value) => {
if (typeof value === "object" && value !== null) {
if (visited.has(value)) {
return;
}
visited.add(value);
}
return value;
};
};
  

JSON.stringify(circObj, replacerFunc());

I was also getting the same error, in my case it was just because of not using await with Users.findById() which returns promise, so response.status().send()/response.send() was getting called before promise is settled (fulfilled or rejected)

Code Snippet

app.get(`${ROUTES.USERS}/:id`, async (request, response) => {
const _id = request.params.id;
try {
// was getting error when not used await
const user = await User.findById(_id);
if (!user) {
response.status(HTTP_STATUS_CODES.NOT_FOUND).send('no user found');
} else {
response.send(user);
}
} catch (e) {
response
.status(HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR)
.send('Something went wrong, try again after some time.');
}
});

I had a similar issue:-
const SampleFunction = async (resp,action) => {
try{
if(resp?.length > 0) {
let tempPolicy = JSON.parse(JSON.stringify(resp[0]));
do something
}
}catch(error){
console.error("consoleLogs.Utilities.XXX.YYY", error);
throw error;
}
.
.
I put await before JSON.parse(JSON.stringify(resp[0])).
This was required in my case as otherwise object was read only.
Both Object.create(resp[0]) and {...resp[0]} didn't suffice my need.

enter image description here

If an object has a different type of property like mentioned in the above image, JSON.stringify() will through an error.