如何基于Node.js和Express实现带双:id参数的REST API
实现Express双参数路由动态获取SQLite数据
核心实现思路
要支持/:client(客户首页)和/:client/:page(客户指定页面)的动态路由,需调整路由匹配顺序(优先匹配更具体的路由),同时修复SQL注入风险和数据库查询逻辑的问题。
1. 调整路由配置(router.js)
修改路由定义,先添加双参数路由,再处理单参数的客户首页请求:
import express from "express"; import { fetchContent } from "../model/model.js"; const router = express.Router(); // 根路径渲染起始页面 router.get("/", function (req, res) { converter(); // 确保converter函数已定义 res.render("../pages/start.ejs"); }); // 双参数路由:/:client/:page router.get("/:client/:page", async function (req, res) { const { client, page } = req.params; // 使用参数化查询避免SQL注入 const sqlQuery = `SELECT page_content FROM ? WHERE page_name = ?;`; const content = await fetchContent(sqlQuery, [client, page]); if (content === "404") { return res.status(404).render("../pages/404.ejs"); } res.status(200).send(JSON.parse(content)); }); // 单参数路由:/:client(默认返回首页) router.get("/:client", async function (req, res) { const { client } = req.params; const sqlQuery = `SELECT page_content FROM ? WHERE page_name = ?;`; // 假设首页的page_name是"home",可根据实际数据库调整 const content = await fetchContent(sqlQuery, [client, "home"]); if (content === "404") { return res.status(404).render("../pages/404.ejs"); } res.status(200).send(JSON.parse(content)); }); export default router;
2. 修复数据库查询函数(model.js)
原fetchContent存在SQL注入风险、结果处理不严谨的问题,修改为支持参数化查询的版本:
import sqlite3 from "sqlite3"; const db = new sqlite3.Database("path/to/my/db.db"); export function fetchContent(sqlQuery, params = []) { return new Promise((resolve, reject) => { db.get(sqlQuery, params, (err, row) => { if (err) { // 数据库错误返回404 resolve("404"); } else if (!row) { // 无匹配数据返回404 resolve("404"); } else { // 返回查询到的页面内容 resolve(row.page_content); } }); }); }
关键修改说明:
- 用
db.get()替代db.all():每个页面对应唯一一行数据,无需获取全部结果 - 支持参数数组+SQLite占位符
?:彻底避免SQL注入风险 - 新增空结果判断:查询不到对应数据时返回404
3. 验证逻辑
- 访问
localhost:8080/fruit:自动查询Fruit表中page_name="home"的内容 - 访问
localhost:8080/fruit/apples:查询Fruit表中page_name="apples"的内容 - 若客户表不存在或页面数据为空,自动返回404页面
内容的提问来源于stack exchange,提问作者pontaLainen
相关产品推荐
相关产品推荐

