【问题标题】:Nodejs : How to download a pdf file from a REST API?Nodejs:如何从 REST API 下载 pdf 文件?
【发布时间】:2020-12-18 00:38:54
【问题描述】:

有一个带有方法 GET 的 API。

https://api.download.com/getxxxxxxx/id

响应不是 JSON 格式。它是一个 PDF(内容类型:application/pdf)。 响应头

Date: Fri, 28 Aug 2020 16:45:35 GMT
Server: Apache/2.4.18 (Ubuntu)
X-Content-Type-Options: nosniff
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
X-Content-Type-Options: nosniff
Vary: Accept
Content-Length: 955006
Content-Type: application/pdf

我试过这种方法

const assessmentDetails = {
        method: 'get',
        url: 'https://api.download.com/getxxxxxxx/id',
        json: false,
        headers: {
            'api-key': ApiKey.assessmentApikey
        }
    };

    const file_name = uuid + "_summary_report.pdf"
    const file = fs.createWriteStream("./reports/" + file_name);
   
       http.get(assessmentDetails, function (res) {

        file.on('open', function () {            
             file.pipe(res);
             console.log.info('download completed: ' + file);
         });

        file.on('error', function (err) {
             console.log.error('' + err);
        });

    });

但它没有写入 pdf 文件。我可以看到一个损坏的文件。请向我建议,如何解决这个问题。如何将PDF文件保存为节点js中API的响应?

编辑:

根据@eol 的回答尝试了以下方法。文件正在下载,但出现 HTTP 解析错误。

        const file_name = uuid + "_summary_report.pdf"
        const file = fs.createWriteStream("./reports/" + file_name);

        try {
            https.get(url, assessmentDetails, function (res) {
                res.pipe(file);

            }).on('response', function (data) {
                res.json({
                    statuscode: 200,
                    message: 'File downloaded successfully',
                });
            })
        }
        catch (error) {
            res.json({
                statuscode: 500,
                message: 'Something went wrong',
                error: error
            });
        }

控制台出错

"level":"error","message":"uncaughtException: Parse Error: Expected HTTP/\nError: Parse Error: Expected HTTP/\n    at TLSSocket.socketOnData (_http_client.js:469:22)\n    at TLSSocket.emit (events.js:315:20)\n    at TLSSocket.EventEmitter.emit (domain.js:483:12)\n    at addChunk (_stream_readable.js:295:12)\n    at readableAddChunk (_stream_readable.js:271:9)\n    at TLSSocket.Readable.push (_stream_readable.js:212:10)\n    at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)","stack":"Error: Parse Error: Expected HTTP/\n    at TLSSocket.socketOnData (_http_client.js:469:22)\n    at TLSSocket.emit (events.js:315:20)\n    at TLSSocket.EventEmitter.emit (domain.js:483:12)\n    at addChunk (_stream_readable.js:295:12)\n    at readableAddChunk (_stream_readable.js:271:9)\n    at TLSSocket.Readable.push (_stream_readable.js:212:10)\n    at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)",

截图 - https://ibb.co/6tfkTZG

【问题讨论】:

    标签: node.js express http request fs


    【解决方案1】:

    您需要将http 更改为https,因为您的请求网址定义为https://...。此外,您需要将响应流通过管道传输到文件流,而不是相反:

    const fs = require('fs');
    const httpLib = require('http') // exchange this for 'https' if your url is https://...
    
    const assessmentDetails = {
        headers: {
            'api-key': ApiKey.assessmentApikey
        }
    }
    
    const fileName = uuid + "_summary_report.pdf"
    const file = fs.createWriteStream("./reports/" + fileName);
    
    const request = httpLib.get("http://api.download.com/getxxxxxxx/id",
        assessmentDetails,
        (response) => {
            response.pipe(file);
        });
    

    【讨论】:

    • 我试过了,但出现错误 - "level":"error","message":"uncaughtException: connect ECONNREFUSED 127.0.0.1:443\nError: connect ECONNREFUSED 127.0.0.1:443\n at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)"
    • 我已经在几分钟前更新了解决方案,您使用的是当前解决方案吗?
    • 感谢您的时间和精力。它正在下载,但 app.js 正在崩溃。我得到了他的错误 - "level":"error","message":"uncaughtException: Parse Error: Expected HTTP/\nError: Parse Error: Expected HTTP/\n at TLSSocket.socketOnData (_http_client.js:469:22)\n at TLSSocket.emit (events.js:315:20)\n at TLSSocket.EventEmitter.emit (domain.js:483:12)\n
    • 嗯,看起来您的网址毕竟是 http。尝试像以前一样将https 换成const http = require('http')
    • 不,我的意思是一个外部库... -> visionmedia.github.io/superagent
    猜你喜欢
    • 2017-10-12
    • 2020-11-24
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-26
    • 2019-02-08
    相关资源
    最近更新 更多