原生JS获取API数据传至Node.js存MongoDB及create函数req参数使用问题
问题修正方案
核心问题说明
- req是Express框架给路由处理函数传入的请求对象,你可以通过它拿到前端调用POST /matches接口时传递的所有参数,比如你代码里缺失的
nameLeague就可以让前端从请求体传给你,通过req.body.nameLeague获取 - 你现有代码还有4个基础错误会导致功能无法运行:
getDataForSheduleCJS没有返回Promise,你无法拿到接口返回的数据,同时Node环境没有alert浏览器API,直接调用会报错- Node环境默认没有
fetch方法,需要先安装node-fetch@2(v2版本支持CommonJS引入),或者替换为axios等请求库 - football-data的赛事查询接口返回的是比赛列表数组,你之前直接取
resp.competition下的字段逻辑错误,需要遍历返回的matches数组批量生成文档 - 你没有等待异步请求的返回结果就调用
save方法,此时拿到的match是Promise对象不是MongoDB文档实例,调用save会直接报错
修正后代码
1. 先安装依赖
npm install node-fetch@2
2. 修正getDataForSheduleCJS函数
const fetch = require('node-fetch'); const personalToken = '替换为你自己的接口令牌'; const getDataForSheduleCJS = (nameLeague) => { // 要return整个Promise链,外部才能await拿到结果 return fetch(`https://api.football-data.org/v2/competitions/${nameLeague}/matches`, { headers: { 'Content-Type': 'application/json', 'X-Auth-Token': personalToken } }).then(resp => resp.json()) .catch((error) => { console.error('拉取赛事数据出错:', error); // 把错误抛出去,外部catch可以统一处理 throw error; }); }
3. 修正MatchController的create方法
const Match = require('../db/models/match'); // 引入上面的getDataForSheduleCJS函数,路径根据你自己的项目结构调整 const { getDataForSheduleCJS } = require('../utils/footballApi'); class MatchController { async showMatches(req, res) { const matches = await Match.find(); res.status(200).json(matches); console.log('show'); } async create(req, res) { try { // 这里就是req的核心用法:拿前端传过来的联赛编码,比如PL是英超,BL1是德甲 const { nameLeague } = req.body; if (!nameLeague) { return res.status(400).json({ error: '缺少联赛编码参数' }); } // 等待第三方接口返回数据 const resp = await getDataForSheduleCJS(nameLeague); // 遍历比赛列表生成文档实例数组 const matchDocs = resp.matches.map(item => new Match({ leagueName: resp.competition.name, date: item.utcDate.slice(0, 10), awayTeam: item.awayTeam.name, homeTeam: item.homeTeam.name, scoreHomeTeam: item.score.fullTime.homeTeam, scoreAwayTeam: item.score.fullTime.awayTeam, })); // 批量插入数据库 await Match.insertMany(matchDocs); res.status(201).json({ count: matchDocs.length, msg: '赛事数据存入成功' }); } catch (e) { console.log('处理出错:', e); res.status(422).json({ errors: e.errors || e.message }); } } } module.exports = new MatchController();
4. 前端调用说明
前端调用POST /matches接口的时候,请求体传入联赛编码即可:
// 前端请求示例代码 fetch('/matches', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ nameLeague: 'PL' }) })
内容的提问来源于stack exchange,提问作者Bezi
相关产品推荐
相关产品推荐

