简单问题: http.get() 如何同步返回給客户端?
发布于 8 年前 作者 zoomquiet 21320 次浏览 最后一次编辑是 4 年前

嗯嗯嗯,这应该是所有学习 node 的人必须过的一关:

  • 使用 http 内置模块,进行url 获取时
  • 因为 node 是异步的,从指定 url 下载数据,直到 end 事件发生时,才完成
  • 但是,作为一个 post 或是 get 请求过程中,就无法简单的,自然思路的返回数据了,

e.g::

app.post '/chk', (req, res) ->
    ...
    http.get options, (res) ->
        data = ''
        res.on 'data', (chunk) ->
            data += chunk.toString()
        res.on 'end', () ->
            answer = JSON.parse(data)
            console.log answer.success
    res.send answer
  • 这时,俺用 curl 什么的访问 127.0.0.1/chk ,給个网址
  • 那么,返回时,怎么也无法简单的获得 answer
  • 除了人工等待几秒,还有什么方案?

ps: 环境是:

  • node > v0.6.8
  • coffee v 1.2.0
  • express v2.5.8
17 回复

javascript - Node.js. Http.get() function is not responding. - Stack Overflow http://stackoverflow.com/questions/8893167/node-js-http-get-function-is-not-responding

javascript - Node.js: Parse JSON object - Stack Overflow http://stackoverflow.com/questions/6486208/node-js-parse-json-object

等等,都是从 console 返回給后台,然而前台要怎么办?

app.post '/chk', (req, res) ->
    ...
    http.get options, (gres) ->
        data = ''
        gres.on 'data', (chunk) ->
            data += chunk.toString()
        gres.on 'end', () ->
            answer = JSON.parse(data)
            console.log answer.success
            res.end answer

在 res.on 的 end 事件中,不论 res.write/send/end 都吼对象没有这个方法,

::

.../app.coffee:44
        return res.end(answer.success);
                   ^
TypeError: Object #<IncomingMessage> has no method 'end'
    at IncomingMessage.<anonymous> (/Users/zoomq/Works/@NAE/no.de/urisaok/app.coffee:44:20)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
    at Socket.ondata (http.js:1147:24)
    at TCP.onread (net.js:354:27)

在 res.on 的 end 事件中,不论 res.write/send/end 都吼对象没有这个方法,

::

.../app.coffee:44
        return res.end(answer.success);
                   ^
TypeError: Object #<IncomingMessage> has no method 'end'
    at IncomingMessage.<anonymous> (/Users/zoomq/Works/@NAE/no.de/urisaok/app.coffee:44:20)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
    at Socket.ondata (http.js:1147:24)
    at TCP.onread (net.js:354:27)

在 res.on 的 end 事件中,不论 res.write/send/end 都吼对象没有这个方法,

::

.../app.coffee:44
        return res.end(answer.success);
                   ^
TypeError: Object #<IncomingMessage> has no method 'end'
    at IncomingMessage.<anonymous> (/Users/zoomq/Works/@NAE/no.de/urisaok/app.coffee:44:20)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
    at Socket.ondata (http.js:1147:24)
    at TCP.onread (net.js:354:27)

在 res.on 的 end 事件中,不论 res.write/send/end 都吼对象没有这个方法,

::

.../app.coffee:44
        return res.end(answer.success);
                   ^
TypeError: Object #<IncomingMessage> has no method 'end'
    at IncomingMessage.<anonymous> (/Users/zoomq/Works/@NAE/no.de/urisaok/app.coffee:44:20)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
    at Socket.ondata (http.js:1147:24)
    at TCP.onread (net.js:354:27)

在 res.on 的 end 事件中,不论 res.write/send/end 都吼对象没有这个方法,

::

.../app.coffee:44
        return res.end(answer.success);
                   ^
TypeError: Object #<IncomingMessage> has no method 'end'
    at IncomingMessage.<anonymous> (/Users/zoomq/Works/@NAE/no.de/urisaok/app.coffee:44:20)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
    at Socket.ondata (http.js:1147:24)
    at TCP.onread (net.js:354:27)

在 res.on 的 end 事件中,不论 res.write/send/end 都吼对象没有这个方法,

::

.../app.coffee:44
        return res.end(answer.success);
                   ^
TypeError: Object #<IncomingMessage> has no method 'end'
    at IncomingMessage.<anonymous> (/Users/zoomq/Works/@NAE/no.de/urisaok/app.coffee:44:20)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
    at Socket.ondata (http.js:1147:24)
    at TCP.onread (net.js:354:27)

哈哈,pythonic都喜欢coffee

必然的,已经完全无法忍受无排版的代码以及多余的各种东西了,

嗯嗯嗯 ,最后用通用的流氓策略搞掂!

  • 找对应的模块 完成异步行为同步返回!

使用dependency injection,把获得的answer注入自定义callbalk中

//post function
function post(url, callback){
    app.post(url,function(req,res){
    ...
    res.on('end',function(){
        ...
        callback(answer);
    });
}

//good seperation
function sendAnswer(ans){
    res.end(ans);
}

//do the job
post('/chk',sendAnswer);

看看有没有什么帮助http://www.9958.pw/post/nodejs_get_html_a

npm install -g xd-synchttp

安装完成后,示例代码如下。

const sync = require('xd-synchttp');
let content = "";
try{
    content = sync.http_get('http://www.csdn.net',0);//0为不超时,其他数值为超时秒数
}
catch(err){
console.log(err);
}

@haojingus 厉害了,六年前的问题给你翻出来了

来自酷炫的 CNodeMD

@zhangmingfeng 我们自己项目遇到同样的问题,写了一个原生模块解决了,发上来方便大家解决这个问题

回到顶部