如何在服务端发起fetch请求 解决React应用客户端请求冗余问题
Express服务端请求天气接口修复方案
Express 本身完全支持向第三方远程服务发起网络请求,你选用的 node-fetch 依赖可以正常实现该能力,现有代码无法运行的核心问题如下:
- 作用域变量冲突:路由回调的响应对象命名为
res,fetch请求成功后的回调接收的响应对象也命名为res,会出现作用域覆盖,无法正常调用上层路由的响应方法 - 未解析第三方接口返回内容:fetch返回的原始响应对象需要调用
.json()方法才能解析为可用的JSON格式数据 - 未将请求结果回传给前端:解析后的天气数据没有通过路由响应对象返回给发起请求的前端
修复后的完整代码
const express = require('express'); const app = express(); const fetch = require('node-fetch'); const port = process.env.PORT || 5000; app.use(express.json()); // 服务启动监听 app.listen(port, () => console.log(`Listening on port ${port}`)); // 测试路由 app.get('/request-info', (req, res) => { res.send({ information: 'information call successful' }); }); // 天气请求路由 app.get('/request-weather', async (req, res) => { try { // 发起第三方天气接口请求,回调响应对象重命名为weatherRes避免变量冲突 const weatherRes = await fetch('http://thisotherwebsite.com/weather-query-that-returns-json', { method: 'GET', headers: {'Accept': 'application/json'} }) // 解析返回的JSON数据 const weatherData = await weatherRes.json() // 将数据返回给前端 res.send(weatherData) } catch (err) { // 错误处理,避免服务崩溃 res.status(500).send({error: '天气信息请求失败'}) } });
这里把原来的Promise链式调用改成了async/await写法,逻辑更清晰易读,也添加了基础错误捕获逻辑,避免第三方接口异常时导致你的服务报错崩溃。
可选优化:添加请求缓存
为了进一步降低第三方天气接口的请求量,避免用户量上涨后触发对方接口限流,可以给天气请求路由添加本地缓存,示例如下:
// 全局缓存对象,key为请求标识,value为缓存数据+缓存时间戳 const weatherCache = { data: null, updateTime: 0 } // 缓存有效期,单位毫秒,这里设置5分钟=300000毫秒,可根据天气数据更新频率调整 const CACHE_TTL = 5 * 60 * 1000 app.get('/request-weather', async (req, res) => { // 缓存未过期时直接返回缓存数据 if (weatherCache.data && Date.now() - weatherCache.updateTime < CACHE_TTL) { return res.send(weatherCache.data) } try { const weatherRes = await fetch('http://thisotherwebsite.com/weather-query-that-returns-json', { method: 'GET', headers: {'Accept': 'application/json'} }) const weatherData = await weatherRes.json() // 更新缓存 weatherCache.data = weatherData weatherCache.updateTime = Date.now() res.send(weatherData) } catch (err) { // 接口异常时如果有旧缓存,优先返回旧缓存,提升用户体验 if (weatherCache.data) { return res.send(weatherCache.data) } res.status(500).send({error: '天气信息请求失败'}) } });
前端调用调整
原来React端直接调用第三方天气接口的代码,改成调用你的Express服务接口即可:
// React组件内请求示例 const fetchWeather = async () => { const res = await fetch('/request-weather') const data = await res.json() // 后续处理逻辑和之前保持一致即可 }
本地开发时如果React和Express服务端口不一致,需要在React项目的配置文件中添加代理规则,转发/request-weather请求到Express服务的地址。
内容的提问来源于stack exchange,提问作者Arthur Edelman
相关产品推荐
相关产品推荐

