node.js axios 回调问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AnjingJingan
V2EX    Node.js

node.js axios 回调问题

  •  
  •   AnjingJingan 2021-09-18 09:42:41 +08:00 6756 次点击
    这是一个创建于 1498 天前的主题,其中的信息可能已经有所发展或是发生改变。

    浏览器发起请求,后端 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=', '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/') }) 
    13 条回复    2021-11-20 22:28:17 +08:00
    Desmondli
        1
    Desmondli  
       2021-09-18 09:45:19 +08:00   1
    response.end() 放到 getData.then 的回调里边
    imherer
        2
    imherer  
       2021-09-18 09:45:35 +08:00
    浏览器可以直接用 axios,直接在浏览器层面用 axios 请求就好了

    如果你自己想要包装的话,就把你 node.js 里的结果写成一个 api 服务,然后再在浏览器里请求这个 api 拿到结果就好了
    xuxuxu123
        3
    xuxuxu123  
       2021-09-18 09:48:19 +08:00   1
    1 楼是对的;
    或者用 async/await,node 服务端 await getData()之后再返回给浏览器
    cw2k13as
        4
    cw2k13as  
       2021-09-18 10:20:40 +08:00
    我怎么感觉你这个代码我看不明白,async 搭配 then ??? 然后 dataPromise 返回的是一个 promise 啊不是结果啊,response.end()也写错位置了,我感觉你没搞懂 async/await,和 promise
    helim
        5
    helim  
       2021-09-18 10:46:06 +08:00
    我猜你是想把 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 就没啥必要用其他复杂的用法
    helim
        6
    helim  
       2021-09-18 10:47:48 +08:00
    3L 说的也对,但是你需要要把 function (request, response)改为 async 函数
    都可以
    libook
        7
    libook  
       2021-09-18 11:26:02 +08:00   1
    回复没法格式化代码,你自己贴到编辑器里格式化一下吧。

    ```
    const http = require('http');

    const server = http.createServer((request, response) => {
    console.log('收到浏览器请求流。');

    // 构造发出请求的 URL
    const url = new URL('http://httpbin.org/post');
    // 添加 Search,也就是 Query string
    url.search = new URLSearchParams({
    'type': "1",
    });

    // 向 httpbin 发送请求流
    const req = http.request(
    url,
    {
    "method": "POST",
    "headers": {
    "Content-Type": "application/x-www-form-urlencoded;charset=",
    "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",
    },
    },
    res => {
    console.log('收到了 httpbin 返回流');

    console.log('将 httpbin 返回流对接到浏览器的返回流。');
    res.pipe(response);
    },
    );

    // 结束 httpbin 请求流
    req.end();
    });

    server.listen(3000);
    ```

    题主这个需求有很多种方式可以实现,最简单的是流( 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 )对接到一个可写流上。
    duan602728596
        8
    duan602728596  
       2021-09-18 11:28:38 +08:00
    哪有这么麻烦?
    async function getData() {
    const res = await axios.post();
    return res.data;
    }

    server.on('request', async function (req, res) {
    const data = await getData();br />
    res.write(data);
    res.end();
    })
    AnjingJingan
        9
    AnjingJingan  
    OP
       2021-09-18 11:57:24 +08:00
    @cw2k13as 对,前面用 async/await 试过没实现,没改全
    AnjingJingan
        10
    AnjingJingan  
    OP
       2021-09-18 17:37:17 +08:00
    @libook 感谢
    WooodHead
        11
    WooodHead  
       2021-11-03 09:52:52 +08:00
    你这个听起来就像是个代理服务,把整个请求转发给另一个地址,我这几天正好做了这个,可以看看这个库: https://www.npmjs.com/package/http-proxy-middleware ,在这里找找例子: https://codexp.io/npm/1/http-proxy-middleware,express,axios,qs
    WooodHead
        12
    WooodHead  
       2021-11-03 09:54:26 +08:00
    我做的是把请求转给 elasticsearch ,用的是这个例子: https://github.com/appbaseio-apps/reactivesearch-proxy-server/blob/master/index.js
    Dotennin
        13
    Dotennin  
       2021-11-20 22:28:17 +08:00
    想知道 V2EX 不支持 markdown 语法吗, 看着那么留言里写代码都是没有高亮和 index 的贼难受.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2353 人在线   最高记录 6679       Select Language
    意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 10:56 PVG 18:56 LAX 03:56 JFK 06:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86