You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Express服务器处理同一端点的多个查询请求

解决方案

针对你的需求,有三种常见的实现方式,你可以根据实际场景选择:

1. 拆分API端点(推荐,符合RESTful规范)

给电影详情和图库图片分别设置独立的接口,前端分别请求不同地址,后端各自处理对应的查询。

前端修改:

// 获取影片详情
useEffect(()=> {
    const fetchMovies = async () => {
      try{
        const res = await axios.get(`/api/movie/${id}`)
        setMovies(res.data)
      } catch(err) {
        console.log(err)
      }
    }
    fetchMovies()
  },[id])

// 获取图库图片
useEffect(()=> {
    const fetchPics = async () => {
      try{
        const res = await axios.get(`/api/movie/${id}/gallery`)
        setPics(res.data)
      } catch(err) {
        console.log(err)
      }
    }
    fetchPics()
  },[id])

后端修改:

// 处理影片详情查询
app.get("/api/movie/:id", (req,res) => {
    const movieId = req.params.id;
    const q = "SELECT * FROM movies WHERE id = ?";
    pool.query(q, [movieId], (err, data) => {
        if (err) return res.json(err);
        // 返回单条影片数据(查询结果为数组,取第一个元素)
        return res.json(data[0]);
    })
})

// 处理图库图片查询
app.get("/api/movie/:id/gallery", (req,res) => {
    const movieId = req.params.id;
    // 假设图库表名为movie_gallery,关联字段是movie_id
    const q = "SELECT * FROM movie_gallery WHERE movie_id = ?";
    pool.query(q, [movieId], (err, data) => {
        if (err) return res.json(err);
        return res.json(data);
    })
})

2. 通过查询参数区分请求

保持同一个API端点,通过URL查询参数(比如type)告诉后端需要返回哪种数据。

前端修改:

// 获取影片详情
useEffect(()=> {
    const fetchMovies = async () => {
      try{
        const res = await axios.get(`/api/movie/${id}?type=details`)
        setMovies(res.data)
      } catch(err) {
        console.log(err)
      }
    }
    fetchMovies()
  },[id])

// 获取图库图片
useEffect(()=> {
    const fetchPics = async () => {
      try{
        const res = await axios.get(`/api/movie/${id}?type=gallery`)
        setPics(res.data)
      } catch(err) {
        console.log(err)
      }
    }
    fetchPics()
  },[id])

后端修改:

app.get("/api/movie/:id", (req,res) => {
    const movieId = req.params.id;
    const type = req.query.type;

    if (type === "details") {
        const q = "SELECT * FROM movies WHERE id = ?";
        pool.query(q, [movieId], (err, data) => {
            if (err) return res.json(err);
            return res.json(data[0]);
        })
    } else if (type === "gallery") {
        const q = "SELECT * FROM movie_gallery WHERE movie_id = ?";
        pool.query(q, [movieId], (err, data) => {
            if (err) return res.json(err);
            return res.json(data);
        })
    } else {
        // 处理参数错误的情况
        return res.status(400).json({message: "无效的请求类型"});
    }
})

3. 单次请求返回所有数据

后端同时查询两张表,把影片详情和图库图片打包成一个对象返回,前端一次请求就能拿到所有需要的数据,减少HTTP请求次数。

前端修改:

useEffect(()=> {
    const fetchMovieData = async () => {
      try{
        const res = await axios.get(`/api/movie/${id}/full`)
        setMovies(res.data.details);
        setPics(res.data.gallery);
      } catch(err) {
        console.log(err)
      }
    }
    fetchMovieData()
  },[id])

后端修改:

app.get("/api/movie/:id/full", (req,res) => {
    const movieId = req.params.id;
    // 并行执行两个查询
    const movieQuery = pool.promise().query("SELECT * FROM movies WHERE id = ?", [movieId]);
    const galleryQuery = pool.promise().query("SELECT * FROM movie_gallery WHERE movie_id = ?", [movieId]);

    Promise.all([movieQuery, galleryQuery])
        .then(([movieResult, galleryResult]) => {
            const movieDetails = movieResult[0][0];
            const galleryPics = galleryResult[0];
            return res.json({
                details: movieDetails,
                gallery: galleryPics
            });
        })
        .catch(err => {
            return res.json(err);
        })
})

注意事项:

  • 所有SQL查询都使用了参数化查询(?占位符),避免SQL注入风险,这是必须的安全实践。
  • 方案1是最符合RESTful设计的,接口职责清晰,易于维护和扩展;方案3适合数据关联性强、需要同时加载的场景,能减少请求开销。

内容的提问来源于stack exchange,提问作者Fabricio Bisso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:34:54