Node/Express获取SerpApi数据并返回给React前端的解决方案
问题核心
你现在的代码有三个明确问题:
google-search-results-nodejs的search.json是回调风格写法,你的handlePictures函数没有返回Promise,路由里写await根本拿不到返回值,只会拿到undefined- 你一开始在controller回调里直接写了
res.send(data),路由层又调用了一次res.json(response),会触发「Can't set headers after they are sent」的重复响应报错 - 你给/pictures路由只绑定了POST方法,常规拉取数据的请求如果用GET发会直接返回404
修正方案
1. 重写controller层
不要在controller里直接操作res对象,把SerpApi的回调包装成Promise,只负责返回数据、抛出错误,和路由层解耦:
//controllers/picturesController.js const SerpApi = require('google-search-results-nodejs'); const search = new SerpApi.GoogleSearch("674d023b72e91fcdf3da14c730387dcbdb611f548e094bfeab2fff5bd86493fe"); // 建议后续把API密钥放到环境变量中读取,不要硬编码提交到公开代码仓库 const handlePictures = async () => { const params = { q: "Coffee", location: "Austin, Texas, United States", hl: "en", gl: "us", google_domain: "google.com" }; return new Promise((resolve, reject) => { search.json(params, (data) => { if (data?.error) return reject(new Error(data.error)); resolve(data); }); }) } module.exports = {handlePictures};
2. 修正路由层逻辑
去掉冗余的响应处理,加错误捕获,根据前端请求方式匹配HTTP方法:
//routes/api/pictures.js const express = require('express') const router = express.Router(); const picturesController= require('../../controllers/picturesController'); router.route('/') // 拉取数据优先用GET方法,和前端axios请求方法保持一致即可 .get(async (req, res, next) => { try { const serpApiData = await picturesController.handlePictures(); res.json(serpApiData); } catch (err) { next(err); // 错误交给你已经配置好的全局错误中间件处理 } }) // 如果前端已经写了POST请求,放开下面这段注释即可 // .post(async (req, res, next) => { // try { // const serpApiData = await picturesController.handlePictures(); // res.json(serpApiData); // } catch (err) { // next(err); // } // }) module.exports = router;
验证方法
服务启动后,直接在浏览器访问http://localhost:3500/pictures,能正常展示SerpApi返回的JSON数据就说明接口调试通了,前端axios直接请求该地址、匹配对应的HTTP方法即可拿到数据,你的CORS配置已经正确,不会出现跨域问题。
内容的提问来源于stack exchange,提问作者evan
相关产品推荐
相关产品推荐

