猿问

使用nodejs下载多个文件不一致,但使用php则不然

我在 nodejs 和 php 上编写了一个脚本,它实现了相同的功能:ping API、检索文件列表、循环遍历每个文件并将它们下载到磁盘上的指定位置。


左边是nodejs,右边是php。


我观察到,在 Nodejs 中每次尝试时,某些文件都会随机失败。经过某种尝试后,所有文件也会成功。在 php 上,每次尝试都是一致的,并且所有文件都可以正常下载。


Nodejs 中是否缺少某些内容,即默认情况下通过下载文件的请求未包含配置/标头?或者下载多个文件需要在nodejs中以不同的方式处理吗?


Nodejs代码:


const http = require('https');

const fs = require('fs');


function getResponse(url, callback) {

    http.get(url, response => {

        let body = '';


        response.on('data', data => {

            body += data

        })


        response.on('end', () => {

            callback(JSON.parse(body))

        })

    })

}



var download = function (url, dest, callback) {

    http.get(url, response => {

        response.on('error', function (err) {

            console.log(err)

        })

            .pipe(fs.createWriteStream(dest))

            .on('close', callback)

    });

};


getResponse('https://wallhaven.cc/api/v1/search?page=1', json => {

    json.data.forEach((item, index) => {

        download(item.path, `files/file-${index}.jpg`, function () {

            console.log('Finished Downloading' + `file-${index}.jpg`)

        });

    })

})

PHP代码


    $client = new \GuzzleHttp\Client();


    $response = $client->get('https://wallhaven.cc/api/v1/search?page=1');


    $json = json_decode((string)$response->getBody());


    $rows = $json->data;


    foreach ($rows as $index => $row) {

        $content = file_get_contents($row->path);


        Storage::put("files/file-$index.jpg", $content);

    }


    return 'done';


元芳怎么了
浏览 85回答 1
1回答

慕无忌1623718

没有任何神奇的标头可以让它在 Node.js 中工作。如果有时有效,而有时请求花费的时间太长,则服务器可能会由于速率限制而默默地丢弃请求。我可以看出 PHP 是同步的,它将每个文件一个接一个地下载到内存中,然后放入一个文件中,而在 Node.js 中,您可以立即触发每个请求并立即处理所有请求,将内容流式传输到文件中。接收到乱序数据包是正常的,TCP 协议可确保它们重新组合在一起。Node.js 能够执行类似的操作,您很可能会遇到服务器的安全功能或其他限制。如果时间不是问题,我建议修改 Node.js 来减慢请求速度,可以通过限制并发请求的数量,也可以逐个执行(最简单的选项,请参阅 、promise、axios 库)async/await。继您的 Reddit 帖子之后,学习 C++ 来完成这项任务很可能不会产生任何好处。事实上,这会困难几个数量级。Node.js 是一个非常强大的平台,其功能远不止下载文件。在不知道问题的真正原因的情况下,除了尝试分析您的请求并了解它们哪里出了问题之外,我无法提供更多建议。
随时随地看视频慕课网APP
我要回答