使用SvelteKit从MongoDB获取JSON时collection属性解构报错如何解决
问题根因
- 混用了MongoDB Node.js驱动的回调写法与async/await异步语法:
client.connect()传入回调函数时,返回值不会被包装为Promise,因此await init()拿到的是undefined,解构collection属性自然报错。 collection.find()返回的是MongoDB查询游标,不能直接序列化返回给前端,需要调用.toArray()转为普通JSON数组。- 每次请求都新建MongoDB连接会严重浪费资源,生产环境需要做连接单例复用。
修改后的完整代码
/src/lib/db.js
import { MongoClient } from 'mongodb' // 连接单例缓存 let client let collection export async function getCollection() { // 已创建连接直接返回复用 if (collection) return { collection } // 生产环境请将uri存入.env环境变量,不要硬编码明文 const uri = "mongodb+srv://careyestes:fLKFXP6fDjpGh6Z@Cluster0.vmomo.mongodb.net/Cluster0?retryWrites=true&w=majority"; client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true }); // 用await写法替代回调,保证异步返回符合Promise规范 await client.connect() collection = client.db("sample_airbnb").collection("listingsAndReviews") return { collection } }
/src/routes/index.js
import { getCollection } from '$lib/db' export async function get(request) { try { const { collection } = await getCollection() // find后调用toArray转为普通数组,limit限制返回条数避免响应过慢 const listings = await collection.find({}).limit(20).toArray() return { status: 200, body: { listings } } } catch (err) { return { status: 500, body: { error: "Could not retrieve db listing", details: err.message } } } }
注意事项
- 请立即修改你的MongoDB Atlas密码,当前密码已经随代码明文泄露,存在数据安全风险
- 建议将数据库连接URI存入SvelteKit的环境变量文件
.env,通过import.meta.env.VITE_MONGO_URI读取,避免敏感信息硬编码 - 大量查询建议添加分页限制,不要一次性返回全量集合数据,避免接口响应过慢
内容的提问来源于stack exchange,提问作者Carey Estes
相关产品推荐
相关产品推荐

