Nodejs axios 回调问题
Nodejs axios 回调问题
浏览器发起请求,后端 node.js 收到浏览器请求后用 axios 请求一个接口,如何把接口的返回结果给浏览器?
const http = require('http')
const axios = require('axios')
const qs = require('qs')
var request = require('request');
// 返回一个 Server 实例
const server = http.createServer()
async function getData (){
let obj = {
'type': "1"
}
url = "http://httpbin.org/post"
const promise = axios.post(url, qs.stringify(obj), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
})
const dataPromise = promise.then((response)=>response.data)
return dataPromise
}
server.on('request', function (request, response) {
console.log('收到客户端的请求了,请求路径是:' + request.url)
response.write('hello')
getData().then((res) => {
// response.write(res)
console.log(res) //res 怎么返回给前端
})
// 告诉客户端,我的话说完了,你可以呈递给用户了
response.end()
})
server.listen(3000, function () {
console.log('服务器启动成功了,http://127.0.0.1:3000/')
})
response.end() 放到 getData.then 的回调里边
浏览器可以直接用 axios,直接在浏览器层面用 axios 请求就好了
如果你自己想要包装的话,就把你 node.js 里的结果写成一个 api 服务,然后再在浏览器里请求这个 api 拿到结果就好了
1 楼是对的;
或者用 async/await,node 服务端 await getData()之后再返回给浏览器
我怎么感觉你这个代码我看不明白,async 搭配 then ??? 然后 dataPromise 返回的是一个 promise 啊不是结果啊,response.end()也写错位置了,我感觉你没搞懂 async/await,和 promise
我猜你是想把 getData 拿到的数据 response.end()过去给客户端,但是 getData 是个异步,是吧?
那可以这样写
async function getData(callback) {
const res = await axios.post(url)
callback(res)
}
server.on(‘request’, function (request, response) {
getData(res => {
response.end(res)
})
})
既然用了 async await 就没啥必要用其他复杂的用法
3L 说的也对,但是你需要要把 function (request, response)改为 async 函数
都可以
回复没法格式化代码,你自己贴到编辑器里格式化一下吧。<br>const http = require('http');<br><br>const server = http.createServer((request, response) => {<br> console.log('收到浏览器请求流。');<br><br> // 构造发出请求的 URL<br> const url = new URL('<a target="_blank" href="http://httpbin.org/post');" rel="nofollow noopener">http://httpbin.org/post');</a><br> // 添加 Search,也就是 Query string<br> url.search = new URLSearchParams({<br> 'type': "1",<br> });<br><br> // 向 httpbin 发送请求流<br> const req = http.request(<br> url,<br> {<br> "method": "POST",<br> "headers": {<br> "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",<br> "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",<br> },<br> },<br> res => {<br> console.log('收到了 httpbin 返回流');<br> <br> console.log('将 httpbin 返回流对接到浏览器的返回流。');<br> res.pipe(response);<br> },<br> );<br> <br> // 结束 httpbin 请求流<br> req.end();<br>});<br><br>server.listen(3000);<br>
题主这个需求有很多种方式可以实现,最简单的是流( Stream )。
浏览器向这个 node 服务发送请求的时候,node 服务会接收到一个来自浏览器的请求流,然后 node 服务向 httpbin 发送一个请求流,httpbin 返回一个返回流,然后像接水管管道一样把 httpbin 的返回流接在 node 服务即将返回给浏览器的返回流,浏览器最终收到了数据。
用流的好处就是不需要自己重建返回给浏览器的返回结构,直接复用上游的返回结构;另一方面 node 服务不需要缓存 httpbin 的整个返回数据,用 async/await 的方案通常会把 httpbin 返回的数据整个存在 node 服务的内存里,小量数据还好,如果是下载大文件的话有撑爆内存的风险。
http 模块的文档在这:
https://nodejs.org/api/http.html
http.createServer 里的回调函数的两个参数类型:
https://nodejs.org/api/http.html#http_class_http_incomingmessage
https://nodejs.org/api/http.html#http_class_http_serverresponse
你可以看到这两个类型都是“Extends: <Stream>”即继承自 Stream,Stream 的文档在这里:
https://nodejs.org/api/stream.html
node 服务返回给浏览器,以及 node 服务发请求给 httpbin,都是属于可写流( Writable Stream ),可写流在写完之后必须调用 end 来结束流。
httpbin 返回给 node 服务的流是可读流( Readable Stream ),你可以把可读流用管道方法( pipe )对接到一个可写流上。
对,前面用 async/await 试过没实现,没改全
感谢
你这个听起来就像是个代理服务,把整个请求转发给另一个地址,我这几天正好做了这个,可以看看这个库: https://www.npmjs.com/package/http-proxy-middleware ,在这里找找例子: https://codexp.io/npm/1/http-proxy-middleware,express,axios,qs
我做的是把请求转给 elasticsearch ,用的是这个例子: https://github.com/appbaseio-apps/reactivesearch-proxy-server/blob/master/index.js
想知道 V2EX 不支持 markdown 语法吗, 看着那么留言里写代码都是没有高亮和 index 的贼难受.😣
在Node.js中使用axios进行HTTP请求时,处理回调(callbacks)和异步操作是非常重要的。axios基于Promise设计,因此更推荐使用Promise或async/await来处理异步请求,而不是传统的回调函数方式。这不仅能提高代码的可读性,还能减少回调地狱(callback hell)的问题。
以下是一个使用axios结合async/await的示例代码:
const axios = require('axios');
async function fetchData() {
try {
const response = await axios.get('https://api.example.com/data');
console.log('Response data:', response.data);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData();
在这个例子中,fetchData
是一个异步函数(由async
关键字定义)。它使用await
关键字等待axios请求的完成。如果请求成功,它会打印响应数据;如果请求失败,它会捕获并打印错误信息。
如果你坚持使用回调函数的方式,虽然不推荐,但也可以这样做:
const axios = require('axios');
axios.get('https://api.example.com/data', function(error, response) {
if (error) {
console.error('Error fetching data:', error);
} else {
console.log('Response data:', response.data);
}
});
在这个回调版本的代码中,axios请求的结果会传递给一个回调函数,该函数检查是否有错误,并相应地处理响应数据或错误信息。然而,这种方法不如使用Promise或async/await来得直观和易于维护。