2013-07-25 9 views
9

Ho riscontrato uno strano comportamento con Node.js http.get. Faccio una richiesta a un URL con ajax e voglio ottenere il risultato nel mio browser. Ma ho solo un pezzo di un contenuto di tag <head> e niente di più, nessun contenuto <body>. Ma se invio il risultato alla console di sistema (console.log(chunk)) ottengo il risultato come voglio ottenere - la pagina intera. Qui sono i miei passi:Node.js` "http.get" non restituisce il corpo della risposta completa a un browser ma solo un pezzo del tag <head>. Come ottenere una risposta completa?

// 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://stackoverflow.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. 
    }); 
}); 

Così nel mio <div id="baz"> ho solo qualche pezzo di <head> tag di http://stackoverflow.com/ richiesta, non <body> tag e il suo contenuto. È tutto quello che ricevo in <div id="baz"> anziché l'intera pagina:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Stack Overflow</title> 
    <link rel="shortcut icon" href="https://cdn.sstatic.net/stackoverflow/img/favicon.ico"> 
    <link rel="apple-touch-icon image_src" href="https://cdn.sstatic.net/stackoverflow/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/stackoverflow/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 

Ma in console.log(chunk) ottengo l'intera pagina stampata nella console come ho detto sopra.

Che cosa sta succedendo? Perché http.get non restituisce la risposta completa nel browser? Cosa mi sono perso? Cosa taglia la risposta?

risposta

14

console.log(chunk); in realtà non log l'intera pagina in una sola volta, ma continua a registrare ogni chunk come più 'data' arriva.

res.end(), d'altra parte, diventa un no-op dopo la prima chiamata mentre chiude la connessione, quindi è incluso solo il 1 chunk.

Che cosa si può fare è res.write() ogni chunk di 'data', in attesa che 'end' a res.end():

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

Oppure, dal momento che result è una Stream.Readable (IncomingMessage) e res è presumibilmente un Stream.Writable (indovinare un ServerResponse), dovresti essere in grado di .pipe():

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

Grazie! La natura asincrona di Nodejs a volte mi fa venire la mente – antongorodezkiy

11

vostro evento data è sparare più volte, ma si può solo "fine" l'output una volta ... probabilmente si dovrebbe refactoring del gestore come segue ...

// In /myapppath 
http.get("http://stackoverflow.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('')); 
    }); 
}); 
+0

Wow, w orchi come un fascino. Grazie. Ora capisco come usarlo. – Green

+0

mi scusi, ma cosa si intende per "ret"? – atripes

+1

@atrioom era un errore di "res" sopra (corretto) ... res è l'oggetto di risposta http per la connessione dal browser client. – Tracker1

Problemi correlati