我正在http://nodejs.org/docs/v0.4.0/api/http.html#http.request上阅读文档,但出于某种原因,我似乎无法真正找到body/data属性在返回的,已完成的响应对象上.
> var res = http.get({host:'www.somesite.com', path:'/'})
> res.finished
true
> res._hasBody
true
Run Code Online (Sandbox Code Playgroud)
它已经完成(http.get为你做了),所以它应该有某种内容.但是没有身体,没有数据,我无法从中读取.身体隐藏在哪里?
yoj*_*o87 167
http.request docs包含如何通过处理data事件接收响应体的示例:
var options = {
host: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST'
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
Run Code Online (Sandbox Code Playgroud)
http.get与http.request做同样的事情,除了它req.end()自动调用.
var options = {
host: 'www.google.com',
port: 80,
path: '/index.html'
};
http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
res.on("data", function(chunk) {
console.log("BODY: " + chunk);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
Run Code Online (Sandbox Code Playgroud)
biz*_*izi 128
我还想补充说http.ClientResponse返回的http.get()有一个end事件,所以这是我收到身体响应的另一种方式:
var options = {
host: 'www.google.com',
port: 80,
path: '/index.html'
};
http.get(options, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
console.log(body);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
Run Code Online (Sandbox Code Playgroud)
mik*_*ana 50
该的await关键字是处理最好的办法,避免了回调和.then()
您还需要使用返回Promises的HTTP客户端. http.get()仍然返回一个Request对象,这样就无法工作了.您可以使用fetch,但它superagent是一个成熟的HTTP客户端,它具有更合理的默认值,包括查询更简单的字符串编码,正确使用mime类型,默认使用JSON以及其他常见的HTTP客户端功能.await将等到Promise有一个值 - 在这种情况下,HTTP响应!
const superagent = require('superagent');
(async function(){
const response = await superagent.get('https://www.google.com')
console.log(response.text)
})();
Run Code Online (Sandbox Code Playgroud)
使用await,一旦返回的promise 有一个值,control就会转到下一行superagent.get().
小智 11
如果你想使用.get,你可以这样做
http.get(url, function(res){
res.setEncoding('utf8');
res.on('data', function(chunk){
console.log(chunk);
});
});
Run Code Online (Sandbox Code Playgroud)
nkr*_*ron 11
在data下载主体的"块"时会多次触发该事件,并且在下载end所有块时发生事件.
现在Node支持Promises,我创建了一个简单的包装器来通过Promise返回连接的块:
const httpGet = url => {
return new Promise((resolve, reject) => {
http.get(url, res => {
res.setEncoding('utf8');
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => resolve(body));
}).on('error', reject);
});
};
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式从异步函数中调用它:
const body = await httpGet('http://www.somesite.com');
Run Code Online (Sandbox Code Playgroud)
Yak*_*ein 10
主体没有完全作为响应的一部分存储,这是因为主体可以包含非常大量的数据,如果将其存储在响应对象上,程序的内存会消耗得非常快。
相反,Node.js 使用一种称为Stream的机制。这种机制允许只保存一小部分数据,并允许程序员决定是在内存中完全使用它还是使用数据的每一部分作为其流动。
有多种方法可以将数据完全消耗到内存中,由于HTTP Response是可读流,因此res对象上的所有可读方法都可用
监听"data"事件并保存传递给回调的块
const chunks = []
res.on("data", (chunk) => {
chunks.push(chunk)
});
res.on("end", () => {
const body = Buffer.concat(chunks);
});
Run Code Online (Sandbox Code Playgroud)
使用这种方法时,您不会干扰流的行为,并且您只收集应用程序可用的数据。
使用"readble"事件并调用res.read()
const chunks = [];
res.on("readable", () => {
let chunk;
while(null !== (chunk = res.read())){
chunks.push(chunk)
}
});
res.on("end", () => {
const body = Buffer.concat(chunks);
});
Run Code Online (Sandbox Code Playgroud)
使用这种方法时,您将完全负责流,直到res.read被调用时,才会将更多数据传递到流中。
使用异步迭代器
const chunks = [];
for await (const chunk of readable) {
chunks.push(chunk);
}
const body = Buffer.concat(chunks);
Run Code Online (Sandbox Code Playgroud)
这种方法与方法类似"data" event。它只会简化范围,并允许整个过程在同一范围内发生。
虽然如上所述,可以完全使用响应中的数据,但如果确实有必要这样做,请始终牢记这一点。在许多情况下,可以简单地将数据定向到其目的地,而无需将其完全保存到内存中。
Node.js 读取流,包括 HTTP 响应,具有执行此操作的内置方法,该方法称为pipe。用法很简单,readStream.pipe(writeStream);.
例如:
如果您的数据的最终目的地是文件系统,您可以简单地打开一个写入文件系统的流,然后pipe将数据发送到 ts 目的地。
const { createWriteStream } = require("fs");
const writeStream = createWriteStream("someFile");
res.pipe(writeStream);
Run Code Online (Sandbox Code Playgroud)
您需要为请求添加一个侦听器,因为node.js是异步的,如下所示:
request.on('response', function (response) {
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
269478 次 |
| 最近记录: |