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:
所以在我的
<!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(''));
});
});