如何在hapi.js处理器中赋值HTTP响应体为变量并解决502报错
错误原因
你的代码无法正常拿到响应、返回502的核心问题有三点:
- 原生
https.request是异步回调API,你没有等待接口响应完成,就直接把请求实例本身传给了响应方法,根本没有拿到实际返回的内容 data事件是分片接收响应数据的,单次触发拿到的只是数据片段,不是完整响应体,且你在事件回调里直接return数据,没有做存储,外层根本访问不到- 没有监听
end事件判断数据接收完成,也没有做请求错误捕获,异常发生时会直接导致接口报错
正确实现
因为你已经用了async函数声明路由处理方法,最简便的方式是把https.request包装为Promise,用await等待完整响应体接收完成后再返回:
const https = require('https') const getDadJokes = async (request, h) => { const dadJokesApi = { hostname: 'icanhazdadjoke.com', method: 'GET', path: '/', headers: { 'Accept': 'text/plain', }, } const jokeText = await new Promise((resolve, reject) => { const req = https.request(dadJokesApi, (res) => { // 设置编码,自动将Buffer类型的分片转为字符串 res.setEncoding('utf8') let responseBody = '' // 逐段拼接接收的数据 res.on('data', (chunk) => { responseBody += chunk }) // 所有数据接收完成后,返回完整响应体 res.on('end', () => { resolve(responseBody) }) }) // 捕获请求阶段的错误 req.on('error', (err) => { reject(err) }) req.end() }) return h.response(jokeText); };
注意事项
- 如果需要请求返回JSON格式数据,把请求头里的
Accept改为application/json,拿到完整responseBody后调用JSON.parse(responseBody)即可转为JS对象使用 - 禁止在
data事件回调中直接拿数据做完整响应处理,HTTP传输大体积内容时会多次触发data事件,只有end事件触发时才代表所有数据传输完成 - 在async函数中使用回调风格的原生API时,必须包装为Promise后调用
await等待执行结果,否则代码不会等待异步操作完成就会继续向下执行,拿到的只会是未完成的请求对象或者空值
内容的提问来源于stack exchange,提问作者Jesaya Fernando Napitupulu
相关产品推荐
相关产品推荐

