【问题标题】:How to download pdf file from data loaded from ajax or fetch calling express route that call our Api via axios?如何从 ajax 加载的数据中下载 pdf 文件或获取通过 axios 调用我们 Api 的调用快速路由?
【发布时间】:2020-12-15 11:26:13
【问题描述】:

我尝试下载我们的 API 生成的 pdf 文件。

流程: 单击“下载”按钮会触发获取快速路线的功能。 路由通过 axios 调用我们的 API。 API 生成一个 pdf 并返回一个原始数据 pdf 文件(字符串)。 路由得到axios的响应。 为了将此响应发送回 fetch,我将响应放入对象 {pdf: response} 并使用 res.json({pdf: response}) 将其发送回。 在 fetch.then() 中,我需要将响应转换为 blob 并在其上使用 URL.createObjectURL 创建一个不可见的下载链接以触发点击并开始下载。

问题: res.json({pdf: response}) 发送的响应不能转换成blob,因为它不是pdf数据,它是一个包含pdf数据的json。

按钮点击触发的动作:

var url = "/routePath";

fetch(url)
    .then(response => response.blob())
    .then(blob => {
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.style.display = 'none';
        a.href = url;
        // the filename you want
        a.download = couponName + '.pdf';
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
    })
    .catch((error) => console.error(error));

服务器端的快速路由处理:

router.get('/routePath', async function(req, res, next) {

    const pdf = await Api.send(req, 'entity', 'action', {data}, {});
    res.json({pdf: pdf});
});

通过 Axios 调用:

const config = require(`../config/config.${process.env.NODE_ENV}.json`);
const axios = require('axios');

module.exports = {
    send: async function(req, entity, action, data, pathValues){
        let response = false;

        try {
            // Prepare headers
            let headers = {'Content-Type': 'application/json'};
            
            // Request
            let axiosConfig = {
                method: 'get',
                headers,
                url: path,
                data: data,
                validateStatus: false
            };
            axiosConfig.params = data;

            response = await axios(axiosConfig);

            if (response.data == '') response.data = {};
            response = response.data;
            response.callSuccess = true;
        } catch(error) {
            console.error(error);
            if (error.response){

                response = error.response.data;
                response.callSuccess = false;
                console.error(response);
            }
            else {
                console.error(error);
            }
            
        }

        return response;
    }

}

【问题讨论】:

  • 您能分享一下您是如何生成 PDF 的吗?
  • 我无权访问 API 文件。

标签: jquery node.js express axios fetch


【解决方案1】:

客户端:

我将 Fetch 切换为 Ajax 以获得更高的兼容性(即)。 我还使用base64ToArrayBuffer进行转换,接收到的pdf数据能够将其转换为blob。

[...]
var url = "/routePath";

    $.ajax({ url: url })
    .done(function(pdf) {
        const arraybuffer = base64ToArrayBuffer(pdf);
        const blob = new Blob([arraybuffer], {type: 'application/pdf'});
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.style.display = 'none';
        a.href = url;
        a.download = 'GoCoupons.' + couponName + '.pdf';
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
    })
    .fail(function(error) {
        console.error(error);
    })

    [...]

function base64ToArrayBuffer(data) {
    var binaryString = window.atob(data);
    var binaryLen = binaryString.length;
    var bytes = new Uint8Array(binaryLen);
    for (var i = 0; i < binaryLen; i++) {
        var ascii = binaryString.charCodeAt(i);
        bytes[i] = ascii;
    }
    return bytes;
}

服务器端:

我没有返回 json,而是从我们的 API 发送 pdf 响应。

router.get('/routePath', async function(req, res, next) {
    const pdf = await Api.send(req, 'entity', 'action', {data}, {});
    res.send(pdf);
});

axios调用还是一样

const config = require(`../config/config.${process.env.NODE_ENV}.json`);
const axios = require('axios');

module.exports = {
    send: async function(req, entity, action, data, pathValues){
        let response = false;

        try {
            // Prepare headers
            let headers = {'Content-Type': 'application/json'};
            
            // Request
            let axiosConfig = {
                method: 'get',
                headers,
                url: path,
                data: data,
                validateStatus: false
            };
            axiosConfig.params = data;

            response = await axios(axiosConfig);

            if (response.data == '') response.data = {};
            response = response.data;
            response.callSuccess = true;
        } catch(error) {
            console.error(error);
            if (error.response){

                response = error.response.data;
                response.callSuccess = false;
                console.error(response);
            }
            else {
                console.error(error);
            }
            
        }

        return response;
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    相关资源
    最近更新 更多