Node.js`“http.get”不会向浏览器返回完整的响应正文,而只返回一个标记。如何获得完整的回复?

时间:2021-02-28 16:58:31

I experience a strange behavior with Node.js http.get. I make a request to a url with ajax and want to get the result into my browser. But I only get some piece of a <head> tag content and nothing more, no <body> content. But if I send the result to system console (console.log(chunk)) I get the result as I want to get - the full page. Here are my steps:

我在Node.js http.get中遇到了一个奇怪的行为。我使用ajax向url发出请求,并希望将结果存入我的浏览器。但我只得到一些标签内容,仅此而已,内容。但是如果我将结果发送到系统控制台(console.log(chunk)),我会得到我想要的结果 - 整个页面。这是我的步骤:

// Simple jQuery Ajax GET
$.ajax({
    type: "GET",
    url: "/myapppath",   // send to my app's url
    data: {foo: "bar"},
    success: onLoad,    // the callback, see just bellow
    error: onError,
    dataType: "text"
});

// With this callback function I want to insert the result into <div id="baz">
function onLoad(resp) {
   document.getElementById("baz").innnerHTML = resp;
}

// In /myapppath
http.get("http://*.com/", function(result) {
   result.setEncoding('utf8');
   result.on("data", function(chunk) {
      console.log(chunk); // this successfully returns the whole page but into system console
      res.end(chunk);   // this returns just a piece of <head> tag into the browser.
   });
});

So in my <div id="baz"> I only get some piece of <head> tag of http://*.com/ request, no <body> tag and its content. That's all I get in <div id="baz"> instead of the whole page:

所以在我的

中,我只得到http://*.com/ request的一些标签,没有标签及其内容。这就是我得到的所有
而不是整个页面:

<!DOCTYPE html>
<html>
<head> 
    <title>Stack Overflow</title>
    <link rel="shortcut icon" href="https://cdn.sstatic.net/*/img/favicon.ico">
    <link rel="apple-touch-icon image_src" href="https://cdn.sstatic.net/*/img/apple-touch-icon.png">
    <link rel="search" type="application/opensearchdescription+xml" title="Stack Overflow" href="/opensearch.xml">

    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://cdn.sstatic.net/js/stub.js?v=dd6898efd655"></script>
    <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/*/all.css?v=8a5907e853ab">

    <link rel="alternate" type="application/atom+xml" title="Feed of recent questions" href="/feeds">
        <script type="text/javascript" defer>
        </script>    
    <script type="text/javascript">          StackExchange.init({"stackAuthUrl":"https://stackauth.com","serverTime":1374771485,"styleCode":true,"enableUserHovercards":true,"site":{"name":"Stack Overflow","description":"Q&A for professional and enthusiast programmers","isNoticesTabEnabled":true,"recaptchaPublicKey":"6LdchgIAAAAAAJwGpIzRQSOFaO0pU6s44Xt8aTwc","enableSocialMediaInSharePopup":true},"user":{"fkey":"b1d105a0cf61e49216c5750a6ad60dec","isAnonymous":true}});
        StackExchange.using.setCacheBreakers({"js/prettify-full.js":"6c261bebf56a","js/moderator.js":"7cf00e91ce39","js/full-anon.js":"c5bf51314708","js/full.js":"02e9182c23d3","js/wmd.js":"2f79c03846d5","js/third-party/jquery.autocomplete.min.js":"e5f01e97f7c3","js/mobile.js":"e8e23ad37820","js/help.js":"6e6623243cf6","js/tageditor.js":"450c9e8426fc","js/tageditornew.js":"b6c68ad4c7dd","js/inline-tag-editing.js":"8e84e8a137f7","js/revisions.js":"7273bb714bba","js/review.js":"2b3ae123e376","js/tagsuggestions.js":"aa48ef6154df","js/post-validation.js":"bb996020492a","js/explore-qlist.js":"1c5bbd79b562","js/events.js":"37756ef3ba47"});
    </script>
    <script type="text/javascript">
        StackExchange.using("gps", function() {
             StackExchange.gps.init(true);
        });
    </script>

        <script type="text/javascript">
            StackExchange.ready(function () {
                $('#nav-tour').click(function () {
                    StackExchange.using("gps", function() {
                        StackExchange.gps.track("aboutpage.click", { aboutclick_location: "headermain" }, true);
                    });
                });
            });
        </script>
</h 

But in console.log(chunk) I get the whole page printed in the console as I said above.

但是在console.log(chunk)中,如上所述,我将整个页面打印在控制台中。

What is going on? Why http.get doesn't return full response into browser? What did I miss? What cuts the response?

到底是怎么回事?为什么http.get没有向浏览器返回完整响应?我错过了什么?是什么削减了回应?

2 个解决方案

#1


14  

console.log(chunk); doesn't actually log the entire page at once, but it does keep logging each chunk as more 'data' arrives.

的console.log(块);实际上并不会立即记录整个页面,但随着更多“数据”的到来,它确实会记录每个块。

res.end(), on the other hand, becomes a no-op after the 1st call as it closes the connection, so only the 1st chunk is included.

另一方面,res.end()在第一次调用后变为无操作,因为它关闭了连接,因此只包含第一个块。

What you can do is res.write() each chunk of 'data', waiting for 'end' to res.end():

你可以做的是res.write()每个'data'块,等待'end'到res.end():

http.get("http://*.com/", function (result) {
    result.on('data', function (chunk) {
        res.write(chunk);
    });
    result.on('end', function () {
        res.end();
    });
});

Or, since result is a Stream.Readable (IncomingMessage) and res is presumably a Stream.Writable (guessing a ServerResponse), you should be able to .pipe() them:

或者,因为结果是Stream.Readable(IncomingMessage)而res可能是Stream.Writable(猜测ServerResponse),你应该能够.pipe()它们:

http.get('http://*.com', function (result) {
    result.pipe(res);
});

#2


11  

Your data event is firing multiple times, but you can only "end" your output once... you should probably refactor your handler as follows...

您的数据事件多次触发,但您只能“结束”输出一次......您应该重构您的处理程序,如下所示......

// In /myapppath
http.get("http://*.com/", function(result) {
    var responseParts = [];
    result.setEncoding('utf8');
    result.on("data", function(chunk) {
        //add this chunk to the output to send
        responseParts.push(chunk);
    });
    result.on("end", function(){
        //now send your complete response
        res.end(responseParts.join(''));
    });
});

#1


14  

console.log(chunk); doesn't actually log the entire page at once, but it does keep logging each chunk as more 'data' arrives.

的console.log(块);实际上并不会立即记录整个页面,但随着更多“数据”的到来,它确实会记录每个块。

res.end(), on the other hand, becomes a no-op after the 1st call as it closes the connection, so only the 1st chunk is included.

另一方面,res.end()在第一次调用后变为无操作,因为它关闭了连接,因此只包含第一个块。

What you can do is res.write() each chunk of 'data', waiting for 'end' to res.end():

你可以做的是res.write()每个'data'块,等待'end'到res.end():

http.get("http://*.com/", function (result) {
    result.on('data', function (chunk) {
        res.write(chunk);
    });
    result.on('end', function () {
        res.end();
    });
});

Or, since result is a Stream.Readable (IncomingMessage) and res is presumably a Stream.Writable (guessing a ServerResponse), you should be able to .pipe() them:

或者,因为结果是Stream.Readable(IncomingMessage)而res可能是Stream.Writable(猜测ServerResponse),你应该能够.pipe()它们:

http.get('http://*.com', function (result) {
    result.pipe(res);
});

#2


11  

Your data event is firing multiple times, but you can only "end" your output once... you should probably refactor your handler as follows...

您的数据事件多次触发,但您只能“结束”输出一次......您应该重构您的处理程序,如下所示......

// In /myapppath
http.get("http://*.com/", function(result) {
    var responseParts = [];
    result.setEncoding('utf8');
    result.on("data", function(chunk) {
        //add this chunk to the output to send
        responseParts.push(chunk);
    });
    result.on("end", function(){
        //now send your complete response
        res.end(responseParts.join(''));
    });
});