Express封装动态URL外部REST API代理接口的实现问题
现有代码问题
- 异步逻辑错误:
getRest内部的HTTP请求是异步回调模式,函数本身没有返回值,你执行res.send(getRest(info))时会直接向前端返回undefined,等回调拿到外部接口数据时,HTTP响应早就已经结束了。 - 变量/引用错误:代码中
Request.get首字母大写,和常规request库的引入命名规则不符,属于未定义变量会直接抛错;前端代码中定义的常量是GET_INFO_API,实际请求时误用了不存在的GET_STEAM_API变量,会直接触发引用错误。 - 缺少异常处理:没有对URL参数缺失、外部接口请求失败、返回格式异常、超时等场景做兼容,出错时会直接导致接口挂起或服务报错。
- 存在安全漏洞:没有做请求域名限制,任意用户都可以传入内网地址、本地文件地址发起请求,属于典型的SSRF风险,可能被利用入侵内网。
正确实现方案
前置依赖安装
使用目前维护状态正常的HTTP请求库实现,避免使用已停止维护的request库:npm install express axios cors
后端完整代码
const express = require('express'); const axios = require('axios'); const cors = require('cors'); const app = express(); const PORT = 3001; // 配置跨域,允许前端本地调试调用 app.use(cors()); // 配置允许请求的外部接口域名白名单,生产环境必须严格配置,禁止放开所有域名 const ALLOWED_HOSTS = [ 'api.steampowered.com', // 按需追加其他你需要调用的外部API域名 ]; app.get('/api/getInfo', async (req, res) => { const targetUrl = req.query.url; // 参数校验 if (!targetUrl) { return res.status(400).json({ code: 400, msg: '缺少必填的url参数' }); } try { const urlInstance = new URL(targetUrl); // 白名单校验 if (!ALLOWED_HOSTS.includes(urlInstance.hostname)) { return res.status(403).json({ code: 403, msg: '当前请求域名不在允许范围内' }); } // 发起服务端请求,设置10秒超时 const externalRes = await axios.get(targetUrl, { timeout: 10000, // 外部接口需要的鉴权头、UA等配置统一在服务端添加,避免前端泄露密钥 headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } }); // 正常返回外部接口数据 return res.json({ code: 200, data: externalRes.data }); } catch (err) { console.error('请求外部接口异常:', err.message); return res.status(500).json({ code: 500, msg: '请求外部接口失败', errMsg: err.message }); } }); app.listen(PORT, () => { console.log(`服务已启动,监听端口${PORT}`); });
前端调用修正代码
修正变量名引用错误即可:
import axios from 'axios'; const GET_INFO_API = "http://localhost:3001/api/getInfo" function getInfo(targetUrl) { return axios.get(GET_INFO_API, { params: { url: targetUrl } }); }
注意:如果外部接口需要POST请求、自定义请求头、传参等能力,可以在当前接口基础上扩展支持对应方法,所有涉及密钥的逻辑必须放在服务端处理,不能透传到前端。
内容的提问来源于stack exchange,提问作者James Radcliff
相关产品推荐
相关产品推荐

