JS实现文件下载示例

在前端开发中,经常需要使用 JavaScript 调用后端接口来实现文件下载功能。以下是几种常见的前端请求方式:

Ajax

Ajax 是前端发送请求时常用的工具,但在处理文件下载时并不推荐使用。这是因为 jQuery 的 $.ajax 在处理 responseTypeblob 时,默认会尝试访问 responseXML,而 responseTypeblob 时无法访问 responseXML,从而导致报错,处理起来较为麻烦。

XMLHttpRequest

所有现代浏览器都内置了 XMLHttpRequest 对象,可用于从服务器请求数据。在处理文件下载时,它是一个比较方便的选择。

示例代码:

function downloadFileWithXHR(url) {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'blob';

    xhr.onload = function () {
        if (xhr.status === 200) {
            const blob = xhr.response;
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);

            // 从响应头中获取 Content-Disposition
            const contentDisposition = xhr.getResponseHeader('Content-Disposition');
            let filename = 'downloaded_file';

            if (contentDisposition) {
                // 使用正则表达式提取文件名
                const filenameMatch = contentDisposition.match(/filename="?([^"]+)"?/);
                if (filenameMatch) {
                    filename = filenameMatch[1];
                    try {
                        // 尝试对文件名进行解码
                        filename = decodeURIComponent(filename);
                    } catch (error) {
                        console.warn('文件名解码失败,使用原始文件名', error);
                    }
                }
            }

            link.download = filename;
            link.click();
            window.URL.revokeObjectURL(link.href);
        }
    };

    xhr.onerror = function () {
        console.error('下载文件时发生错误');
    };

    xhr.send();
}

// 调用示例
downloadFileWithXHR('/api/xxxxxxxxxxxxxx');

fetch

fetch 是 JavaScript 自带的一个发送请求的 API,自 ES6 引入以来,其功能比 XMLHttpRequest 更强大,在处理文件下载时也更加便捷。

示例代码:

async function downloadFileWithFetch(url) {
    try {
        const response = await fetch(url);
        if (response.ok) {
            const blob = await response.blob();
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);

            // 从响应头中获取 Content-Disposition
            const contentDisposition = response.headers.get('Content-Disposition');
            let filename = 'downloaded_file';

            if (contentDisposition) {
                // 使用正则表达式提取文件名
                const filenameMatch = contentDisposition.match(/filename="?([^"]+)"?/);
                if (filenameMatch) {
                    filename = filenameMatch[1];
                    try {
                        // 尝试对文件名进行解码
                        filename = decodeURIComponent(filename);
                    } catch (error) {
                        console.warn('文件名解码失败,使用原始文件名', error);
                    }
                }
            }

            link.download = filename;
            link.click();
            window.URL.revokeObjectURL(link.href);
        }
    } catch (error) {
        console.error('下载文件时出错:', error);
    }
}

// 调用示例
downloadFileWithFetch('/api/xxxxxxxxxxxxxxxxxxxxxx');

可以根据项目需求和实际情况选择合适的方法来实现前端文件下载功能。

posted @ 2025-03-28 12:28  地球上的张先生  阅读(443)  评论(0)    收藏  举报