Node.js循环引用转JSON错误:依赖POST的GET请求排查
错误详情
完整错误信息如下:
TypeError: Converting circular structure to JSON --> starting at object with constructor 'Socket' | property 'parser' -> object with constructor 'HTTPParser' --- property 'socket' closes the circle
需求与实现
我想要实现一个依赖POST请求的GET查询功能,具体代码如下:
const postPrinterData = (request, response) => { const printer_id = parseInt(request.body.printer_id, 10); console.log('收到printer_id:', printer_id); getPrinter_material(printer_id, response); }; const getPrinter_material = (printer_id, response) => { pool.connect((error, client, release) => { if (error) { throw error; } const query = { text: 'SELECT pr.printer_id, m.material FROM printer_material pm JOIN printer pr ON pm.printer_id = pr.printer_id JOIN material m ON pm.material_id = m.material_id WHERE pr.printer_id = $1;', values: [printer_id], } client.query(query, (error, results) => { release(); if (error) { throw error; } response.json([...results.rows]); }); }); }; module.exports = { getPrinter_material, postPrinterData, };
代码导出配置
const http = require('http'); const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const db = require('./pool'); const app = express(); const port = 3000; app.use(bodyParser.json()); app.use( bodyParser.urlencoded({ extended: true, }) ); app.use(cors()); app.get('/printer_material', db.getPrinter_material); app.post('/printerData', db.postPrinterData); http.createServer(app).listen(port, () => { console.log(`应用运行在端口 ${port}。`); });
排查尝试
我用下面的代码做了排查:
console.log(results); console.log(JSON.stringify(results));
确认查询结果存在且能正常转为JSON格式,但还是出现了上面的循环引用转JSON错误,搞不懂问题出在哪。
前端代码
const selectElement1 = document.getElementById('select1'); const selectElement2 = document.getElementById('select2'); const selectElement3 = document.getElementById('select3'); const departmentSelect = document.querySelector('#department'); function createOption(value, text) { const option = document.createElement('option'); option.value = value; option.textContent = text; return option; } function loadSelectOptions1(url, selectElement) { fetch(url) .then(response => response.json()) .then(data => { data.forEach(item => { const option = createOption(item.printer_id, item.printer); selectElement.appendChild(option); }); }) .catch(error => { console.error(error); // 处理错误 }); } function loadSelectOptions2(url, selectElement) { fetch(url) .then(response => response.json()) .then(data => { data.forEach(item => { const option = createOption(item.printer_id, item.material); selectElement.appendChild(option); }); }) .catch(error => { console.error(error); // 处理错误 }); } function loadPrinters() { loadSelectOptions1('http://:3000/printerCB', selectElement2); } function loadMaterial() { loadSelectOptions2('http://:3000/printer_material_defolt', selectElement3); } window.addEventListener('DOMContentLoaded', () => { loadPrinters(); loadMaterial(); }); Promise.all([ fetch('http://:3000/departament').then(response => { if (!response.ok) { throw new Error('数据加载错误'); } return response.json(); }), fetch('http://:3000/type_work').then(response => { if (!response.ok) { throw new Error('数据加载错误'); } return response.json(); }) ]) .then(([departamentData, typeWorkData]) => { const departamentOptions = departamentData.map(item => createOption(item.departament, item.departament)); departmentSelect.append(...departamentOptions); const typeOptions = typeWorkData.map(item => createOption(item.type_work, item.type_work)); selectElement1.append(...typeOptions); selectElement1.addEventListener('change', () => { const selectedValue = selectElement1.value; selectElement2.innerHTML = ''; if (selectedValue === '黑白打印') { loadSelectOptions1('http://:3000/printerCB', selectElement2); } else if (selectedValue === '彩色打印') { loadSelectOptions1('http://:3000/printerColor', selectElement2); } }); }) .catch(error => { console.error(error); }); selectElement2.addEventListener('change', () => { const selectedPrinter = selectElement2.value; // 发送选中的printer_id到服务器 fetch('http://:3000/printerData', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ printer_id: selectedPrinter }) }) .then(response => { if (!response.ok) { throw new Error('数据发送错误'); } }) .catch(error => { console.error(error); }); });
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

