为什么用http.request获取的网页源码,写入本地的文件的时候不是整个网页
发布于 11 年前 作者 sirzxj 5650 次浏览 最后一次编辑是 8 年前

var req = http.request({ host: ‘www.qq.com’, method: ‘get’ }, function(res) { res.setEncoding(‘utf8’); res.on(‘data’, function(data) { fs.writeFile(‘test.html’, data); }); }); req.end();

如题,上面的test.html文件打开后,不是www.qq.com那个网页的全部源码,只有部分,请问如何解决?

6 回复

页面太长,所以会分成几个部分,分别触发data事件。你这样写的结果就是只保存了最后的一个部分。应当先在内存中缓冲,最后一次性写入文件

var http = require('http'),
	fs = require('fs');

http.get('http://www.qq.com', function( res ){
	res.on('error', function(e){
		console.log(e);
	}).pipe(fs.createWriteStream('qq.html'));
});

接收完数据后会触发end事件: 正确写法如下: var req = http.request({ host: ‘www.qq.com’, method: ‘get’ }, function(res) { res.setEncoding(‘utf8’); var html = []; res.on(‘data’, function(data) { html.push(data); }); res.on(‘end’,function(){ fs.writeFile(‘test.html’, html.join("")); }); }); req.end();

要说答案3楼的是最佳的,我在这里再说具体点 问题的关键是楼主用了fs.writeFile方法,请看它的源码: 来自lib/fs.js

fs.writeFile = function(path, data, encoding_, callback) {
  var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8');
  var callback_ = arguments[arguments.length - 1];
  callback = (typeof(callback_) == 'function' ? callback_ : null);
  fs.open(path, 'w', 438 /*=0666*/, function(openErr, fd) {
    if (openErr) {
      if (callback) callback(openErr);
    } else {
      var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data,
          encoding);
      writeAll(fd, buffer, 0, buffer.length, 0, callback);
    }
  });
};

可以看到它使用fs.open方法,使用使用了w模式,而这个模式表示,如果文件不存在则创建或者清空它。于是在Buffer写完64K之后就清空了一遍test.html。要知道QQ的首页少说得有300来K。于是就成这结果了。

res.on(‘end’)

回到顶部