最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Node.js和请求

网站源码admin15浏览0评论

Node.js和请求

Node.js和请求

我想使用请求库下载文件。这很简单:

request({
    url: url-to-file
}).pipe(fs.createWriteStream(file));

由于URL是由用户提供的(对于我来说),我想限制我的应用程序将下载的最大文件大小-假设为10MB。我可以像这样依靠content-length标头:

request({
    url: url-to-file
}, function (err, res, body) {
    var size = parseInt(res.headers['content-length'], 10);

    if (size > 10485760) {
        // ooops - file size too large
    }
}).pipe(fs.createWriteStream(file));

问题是-这有多可靠?我猜这个回调将被称为after文件已下载,对吗?但是,如果有人提供文件的URL为1 GB,为时已晚。我的应用程序将首先下载这1 GB的文件,只是为了检查(在回调中)该文件太大。

我也在考虑好的旧Node的http.get()方法。在这种情况下,我会这样做:

var opts = {
    host: host,
    port: port,
    path: path
};

var file = fs.createWriteStream(fileName),
    fileLength = 0;

http.get(opts, function (res) {
    res.on('data', function (chunk) {
        fileLength += chunk.length;

        if (fileLength > 10485760) { // ooops - file size too large
            file.end();
            return res.end();
        }

        file.write(chunk);
    }).on('end', function () {
        file.end();
    });
});

您建议哪种方法限制下载最大文件大小,而不实际下载整个文件并检查其大小呢?

回答如下:

我实际上会使用您已经讨论过的两种方法:检查content-legnth标头,并观察数据流以确保它不超出您的限制。

为此,我首先向URL发出HEAD请求,以查看content-length标头是否可用。如果大于限制,则可以就此停下来。如果不存在或小于限制,请进行实际的GET请求。由于HEAD请求只会返回标头,而不会返回实际内容,因此这将有助于快速清除具有有效content-length的大文件。

接下来,进行实际的GET请求,并观察传入的数据大小以确保它不超出您的限制(可以通过请求模块来完成;请参见下文)。无论HEAD请求是否找到content-length标头,作为完整性检查(服务器可能躺在content-length周围),您都希望这样做。

类似这样的东西:

var maxSize = 10485760;

request({
    url: url,
    method: "HEAD"
}, function(err, headRes) {
    var size = headRes.headers['content-length'];
    if (size > maxSize) {
        console.log('Resource size exceeds limit (' + size + ')');
    } else {
        var file = fs.createWriteStream(filename),
            size = 0;

        var res = request({ url: url });

        res.on('data', function(data) {
            size += data.length;

            if (size > maxSize) {
                console.log('Resource stream exceeded limit (' + size + ')');

                res.abort(); // Abort the response (close and cleanup the stream)
                fs.unlink(filename); // Delete the file we were downloading the data to
            }
        }).pipe(file);
    }
});

使用请求模块查看传入数据大小的技巧是,在开始将其管道传输到文件流之前,将其绑定到响应上的data事件(就像您正在考虑使用http模块那样)。如果数据大小超出最大文件大小,请调用响应的abort()方法。

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论