Node.js后端req.query解析类型异常致Mongo查询无结果的解决方法
解决GET请求查询参数类型转换问题
由于GET请求的查询参数会被自动序列化为字符串,导致后端拿到的布尔值helped变成了'true'、数值dateAdded变成了'-1',无法匹配MongoDB中的数据类型。以下是几种可行的解决方法:
方案1:手动指定字段类型转换
如果需要转换的字段固定,直接针对特定字段做类型转换,简单直接:
async getAllEvents(req, res, database, collection) { try { let { filter, sort } = req.query; // 将字符串形式的布尔值转为实际布尔类型 if (filter?.helped) { filter.helped = filter.helped === 'true'; } // 将字符串形式的排序值转为数字类型 if (sort?.dateAdded) { sort.dateAdded = parseInt(sort.dateAdded, 10); } const events = await mongo .getClient() .db(database) .collection(collection) .find(filter) .sort(sort) .toArray(); res.json(events); } catch (error) { return res.status(400).json({ message: "err_get_events" }); } }
方案2:通用递归类型转换函数
如果有大量嵌套字段或不确定的字段需要转换,可以写一个通用函数递归处理所有值:
// 递归转换查询参数中的布尔、数值类型 function parseQueryParams(obj) { if (typeof obj !== 'object' || obj === null) return obj; Object.keys(obj).forEach(key => { const value = obj[key]; // 转换布尔值 if (value === 'true') { obj[key] = true; } else if (value === 'false') { obj[key] = false; } // 转换数值(排除非数字字符串) else if (!isNaN(value) && typeof value === 'string') { obj[key] = Number(value); } // 递归处理嵌套对象 else if (typeof value === 'object') { parseQueryParams(value); } }); return obj; } // 在接口中使用 async getAllEvents(req, res, database, collection) { try { let { filter, sort } = req.query; // 对filter和sort做类型转换 filter = parseQueryParams(filter); sort = parseQueryParams(sort); const events = await mongo .getClient() .db(database) .collection(collection) .find(filter) .sort(sort) .toArray(); res.json(events); } catch (error) { return res.status(400).json({ message: "err_get_events" }); } }
方案3:前后端配合传JSON字符串
前端将复杂参数转为JSON字符串后传递,后端再解析为对象,能完全保留原始类型:
前端修改:
const getAllEvents = async () => { const query = settings.query; await axios .get(Constants.BASE_URL + '/' + settings.urlprefix + '/get', { params: { filter: JSON.stringify({ helped: true }), sort: JSON.stringify({ dateAdded: -1 }) } }) .then((res) => { setEvents(res.data); }) .catch((err) => console.log(err?.response?.data?.message)); };
后端解析:
async getAllEvents(req, res, database, collection) { try { let { filter, sort } = req.query; // 将JSON字符串解析为对象 filter = JSON.parse(filter); sort = JSON.parse(sort); const events = await mongo .getClient() .db(database) .collection(collection) .find(filter) .sort(sort) .toArray(); res.json(events); } catch (error) { return res.status(400).json({ message: "err_get_events" }); } }
方案4:配置Express的Query解析器(如果使用Express框架)
Express默认使用qs库解析查询参数,可以通过配置开启自动类型转换:
const express = require('express'); const qs = require('qs'); const app = express(); // 配置query解析选项,自动转换数值、布尔类型 app.set('query parser', (str) => qs.parse(str, { parseValues: true, // 启用自动类型转换 allowPrototypes: true }));
配置后,后端直接使用req.query中的filter和sort即可,无需额外转换。
内容的提问来源于stack exchange,提问作者Dmitry Borisenko
相关产品推荐
相关产品推荐

