如何在Express页面中渲染Fetch获取的API数据?
问题分析与解决步骤
核心问题点
- 路由回调无返回值:
await fetchAdvice().then((advice) => { advice.text.toUpperCase() })里的箭头函数未返回处理后的值,导致传给模板的advice为undefined - 请求失败无兜底处理:
fetchAdvice函数在请求返回非成功状态时,没有返回值或错误处理,会引发后续逻辑异常 - 模板输出对象而非文本:
fetchAdvice返回的是包含text属性的对象,模板直接输出{{advice}}会显示[object Object]
修正代码
1. 修正predictions.js
补充API地址、错误处理,直接返回处理好的大写文本:
const fortunes = ['Conquer your fears or they will conquer you.', 'Rivers need sources.'] const url_random = 'https://api.adviceslip.com/advice' // 补充公开API地址 const fetchAdvice = async () => { try { const res = await fetch(url_random) if (!res.ok) throw new Error('请求建议失败') const { slip: advice } = await res.json() // 适配API返回结构 return advice.text.toUpperCase() } catch (err) { console.error(err) return '暂时无法获取建议,请稍后再试' // 请求失败时返回兜底提示 } } export { fortunes, fetchAdvice }
2. 修正Express路由代码
简化异步逻辑,避免混用await与.then():
import { fortunes, fetchAdvice } from './predictions.js' import path from 'path' app.engine('.hbs', engine({ extname: '.hbs' })) app.set('view engine', '.hbs') app.set('views', './views') app.use(express.static(path.resolve(process.cwd(), 'static'))) app.use(express.json()) app.use(express.urlencoded({ extended: false })) app.get('/about', async (req, res) => { const randomFortune = fortunes[Math.floor(Math.random() * fortunes.length)] const advice = await fetchAdvice() // 直接获取处理好的文本 res.render('about', { fortune: randomFortune, advice }) })
3. 修正Handlebars模板(about.hbs)
直接输出文本即可:
{{#if fortune}} <p>Your prediction for today: {{fortune}}</p> {{/if}} {{#if advice}} <p>Your advice for today: {{advice}}</p> {{/if}}
可选方案(保留原始对象)
若需fetchAdvice返回原始对象,可调整如下:
// predictions.js中返回对象 return advice // 路由中处理文本 const adviceData = await fetchAdvice() const advice = adviceData ? adviceData.text.toUpperCase() : '获取建议失败'
模板无需修改,直接输出{{advice}}即可。
内容的提问来源于stack exchange,提问作者user22790531
相关产品推荐
相关产品推荐

