浏览器发起请求,后端 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/')
})
1
Desmondli 2021-09-18 09:45:19 +08:00 1
response.end() 放到 getData.then 的回调里边
|
2
imherer 2021-09-18 09:45:35 +08:00
浏览器可以直接用 axios,直接在浏览器层面用 axios 请求就好了
如果你自己想要包装的话,就把你 node.js 里的结果写成一个 api 服务,然后再在浏览器里请求这个 api 拿到结果就好了 |
3
xuxuxu123 2021-09-18 09:48:19 +08:00 1
1 楼是对的;
或者用 async/await,node 服务端 await getData()之后再返回给浏览器 |
4
cw2k13as 2021-09-18 10:20:40 +08:00
我怎么感觉你这个代码我看不明白,async 搭配 then ??? 然后 dataPromise 返回的是一个 promise 啊不是结果啊,response.end()也写错位置了,我感觉你没搞懂 async/await,和 promise
|
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 就没啥必要用其他复杂的用法 |
6
helim 2021-09-18 10:47:48 +08:00
3L 说的也对,但是你需要要把 function (request, response)改为 async 函数
都可以 |
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=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", }, }, 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 )对接到一个可写流上。 |
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(); res.write(data); res.end(); }) |
9
AnjingJingan OP @cw2k13as 对,前面用 async/await 试过没实现,没改全
|
10
AnjingJingan OP @libook 感谢
|
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
|
12
WooodHead 2021-11-03 09:54:26 +08:00
我做的是把请求转给 elasticsearch ,用的是这个例子: https://github.com/appbaseio-apps/reactivesearch-proxy-server/blob/master/index.js
|
13
Dotennin 2021-11-20 22:28:17 +08:00
想知道 V2EX 不支持 markdown 语法吗, 看着那么留言里写代码都是没有高亮和 index 的贼难受.😣
|