如何在 Node.js 中使用重定向从 https 链接下载 MP4 文件?

问题描述

我再次遇到一个我无法解决的问题,我正在学习 Node.js,还有很多我不知道的东西。事情是这样的,我有一个名为 downloader.js

文件
const https = require ('https')
const fs = require ('fs')
const path = require ('path')

function downloader (url,callback) {

    const filename = path.basename (url)

    const req = https.get (url,(res) => {
        const file = fs.createWriteStream (`$ {filename} .mp4`)
        res.pipe (file)

        file.on ("error",(error) => {
            console.log (`There was an error writing the file. Details: $ {error}`)
        })

        file.on ("close",() => {
            callback (filename)
        })

        file.on ('finish',() => {
            file.close ()
            console.log ("Completely downloaded.")
        })
    })

    req.on ("error",(error) => {
        console.log (`Error downloading file. Details: $ {error}`)
    })
}

module.exports = {
    downloader
}

我有一个视频,我通过调用 Zoom api 获取下载 URL,链接如下:https://us02web.zoom.us/rec/download/06L34fQudvvSaAGYJ6Chk6RC0fuV-ebwyu9Ar_Ihrm4WRmD3xbpPAjnYfIFInOBz1PBPPAjnYPhoJlf4p3xbpPAjnYFIFIXMD3xbpPAjnYFIFIXMD3xbpPAjnYphoJlf4

调用下载器功能时,一切正常,我下载的是mp4格式的文件,但问题是它不是mp4格式的完整700MB视频,而是mp4格式的html文档。

Here you can see what I mean

我不明白为什么文件下载不正确。当我使用任何其他类型的文件(例如 jpeg 图像)执行此操作时,它可以毫无问题地下载它,但是使用 mp4 格式我无法下载文件。你认为发生了什么?

解决方法

鉴于您发布的链接指向一个错误页面,指出录音不存在,我无法确认此解决方案是否有效。

但是,假设它的功能类似于其他录制链接,那么当您在网络浏览器中导航到该位置时,您会被自动重定向到一个新的 uri 以自动开始下载。

假设是这种情况,您实际上要寻找的是如何跟踪外部 API 请求的重定向。

我会推荐 npm axios 包,因为它会自动跟随重定向。

然后您可以执行以下操作:

const axios = require('axios');
const fs = require('fs');
const path = require('path');

function downloader(url,callback) {
    axios({
        method: 'get',url: url,responseType: 'stream'
    })
        .then(function (response) {
            return new Promise((resolve,reject) => {
                const filename = path.basename(url);
                const file = fs.createWriteStream(`${filename}.mp4`);
                response.data.pipe(file);

                file.on("error",(error) => {
                    return reject(`There was an error writing the file. Details: $ {error}`);
                });

                file.on('finish',() => {
                    file.close();
                });

                file.on('close',() => {
                    return resolve(filename);
                });
            });
        })
        .catch(function (error) {
            // handle error
            console.log(error);
        })
        .then(function (filename) {
            callback(filename);
        })
}

module.exports = {
    downloader
};

你也可以直接返回 axios 承诺,让你的下载器函数返回一个 Promise 而不是接受回调的函数。

如果您想保留 https 变量,也可以尝试使用 follow-redirects 包。