Node中Fetch发起的getDocuments请求一直挂起,求问题排查
问题:Node环境中Fetch发起的getDocuments请求始终处于pending状态无法完成
我在Node环境中使用Fetch发起GET请求时,getDocuments请求始终处于pending状态无法完成,相关代码如下:
App.js
import React, { useState, useEffect } from 'react'; import Grid from './Grid'; import apis from '../api/index'; export default function App(props) { const [documents, setDocuments] = useState([]); useEffect(() => { async function initialize() { await apis.getDocuments().then(documents => { setDocuments(documents.data.data); }); } initialize(); }, []); return ( <Grid documents={documents} /> ) }
Controller.js
最初写法:
const fetch = require('node-fetch'); exports.getDocuments = async (req, res) => { // added 'return' before fetch return fetch('EXTERNAL API ENDPOINT', { method: 'GET', headers: {"api-key": "API KEY"} }) .then(res => res.json()) .then(json => { console.log(json); return json }).catch(err => console.log(err)); };
尝试过的写法:
// added cors exports.getDocuments = async () => { console.log("getting documents..."); const response = await fetch(URL, { method: 'GET', mode: 'cors', headers: { "Content-Type": "application/json", "x-api-key": "KEY" } }) const result = await response.json(); console.log('result', result); return result; };
server index.js
const express = require('express'); const cors = require('cors'); const { getDocuments } = require('./controllers/Controller'); const router = require('./routes'); const app = express(); // enable CORS for all origins to allow development with local server app.use(cors({credentials: true, origin: "http://localhost:3002"})); app.use('/api', router); app.get('/', (req, res) => { res.send('This is the backend/API'); }) app.set('port', process.env.PORT || 4200); const server = app.listen(app.get('port'), () => { console.log(`Express running on port ${server.address().port}`); });
请问我遗漏了什么导致请求无法完成?
问题分析与修复方案
核心问题出在Controller.js的getDocuments路由处理函数上:
第一个版本的问题:
虽然调用了外部API并拿到了结果,但没有通过Express的res对象向前端返回响应。Express路由处理函数必须调用res.send()、res.json()这类方法来结束请求响应周期,否则前端请求会一直处于pending状态等待响应。第二个版本的问题:
直接去掉了req和res参数,完全不符合Express路由处理函数的要求——没有res对象根本无法给前端返回任何内容,请求自然会挂起。
修复后的Controller.js代码
const fetch = require('node-fetch'); exports.getDocuments = async (req, res) => { try { const response = await fetch('EXTERNAL API ENDPOINT', { method: 'GET', headers: {"api-key": "API KEY"} }); const json = await response.json(); console.log(json); // 关键:用res.json向前端返回结果,结束请求周期 res.json(json); } catch (err) { console.log(err); // 发生错误时也要返回错误响应,避免请求挂起 res.status(500).json({ error: '获取文档失败' }); } };
额外注意点
- 确保你的路由文件(
router)中正确配置了getDocuments的路由映射,比如:const express = require('express'); const router = express.Router(); const { getDocuments } = require('../controllers/Controller'); router.get('/documents', getDocuments); module.exports = router; - 前端调用的
apis.getDocuments()要对应正确的后端接口路径(比如/api/documents)。
内容的提问来源于stack exchange,提问作者dikuw
相关产品推荐
相关产品推荐

