如何打开 POST 生成的 CSV 文件

How to open a CSV file generated by POST

我正在尝试实现这些看似简单的要求但找不到方法:

问题主要是,如何将JSON作为请求体传递?最常见的技术似乎是隐藏 HTML 表单来触发下载,但是 HTML 表单无法在正文中发送 JSON 数据。而且我找不到任何方法来使用 XMLHttpRequest 触发下载对话框...

有什么想法吗?

我指定了 Angular 但任何通用的 JS 解决方案也非常受欢迎!

我终于找到了一个可以满足我所有要求的解决方案,并且可以在 IE11、FF 和 Chrome 中运行(并且在 Safari 中降低了某种程度的 OK...)。

想法是创建一个包含响应数据的 Blob 对象,然后强制浏览器将其作为文件打开。对于 IE(专有 API)和 Chrome/FF(使用 link 元素)略有不同。

这是实现,作为一个小型 Angular 服务:

myApp.factory('Download', [function() {
    return {
        openAsFile : function(response){

            // parse content type header
            var contentTypeStr = response.headers('Content-Type');
            var tokens = contentTypeStr.split('/');
            var subtype = tokens[1].split(';')[0];
            var contentType = {
                type : tokens[0],
                subtype : subtype
            };

            // parse content disposition header, attempt to get file name
            var contentDispStr = response.headers('Content-Disposition');
            var proposedFileName = contentDispStr ? contentDispStr.split('"')[1] : 'data.'+contentType.subtype;

            // build blob containing response data
            var blob = new Blob([response.data], {type : contentTypeStr});

            if (typeof window.navigator.msSaveBlob !== 'undefined'){
                // IE : use proprietary API
                window.navigator.msSaveBlob(blob, proposedFileName);
            }else{
                var downloadUrl = URL.createObjectURL(blob);

                // build and open link - use HTML5 a[download] attribute to specify filename
                var a = document.createElement("a");

                // safari doesn't support this yet
                if (typeof a.download === 'undefined') {
                    window.open(downloadUrl);
                }

                var link = document.createElement('a');
                link.href = downloadUrl;
                link.download = proposedFileName;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            }
        }
    }
}]);

响应参数需要一个 $http 响应对象。下面是一个使用 POST 请求的例子:

$http.post(url, {property : 'value'},  {responseType: 'blob'}).then(function(response){
    Download.openAsFile(response);
});

注意 responseType 参数。如果没有这个,我的 CSV 数据将被读取为文本并以 UTF-8(或 16)格式存储在内存中,随后文件以相同的编码保存,导致 Excel 无法识别 éè 等特殊字符. 由于我的 CSV 旨在由 Excel 打开,服务器将它们编码为 Windows 1252,我想保持这种状态。将 responseType 参数设置为 blob 可实现此目的。

免责声明:它适用于任何文件类型。但我只用 CSV 文件测试过它!二进制文件的行为可能会有所不同!