在前端下载ANSI zip文件,由C#后端生成

Download ANSI zip file in front end, generated by C# back end

我有一个 C# 后端在内存中生成一个 zip 文件(使用 System.IO.Compression)并将其发送到我的前端。如果我在发送之前下载 zip 文件,它运行良好并且采用 ANSI 编码(在记事本 ++ 上找到)。

这就是我目前 return 我的文件的方式,我尝试了很多不同的方法来做到这一点,例如简单地 return 没有 headers 的文件,但现在它看起来像这样:

[HttpPost]
[Route("GetUserWorkContext")]
public async Task<IActionResult> GetUserWorkContext([FromBody] GetUserWorkContextRequest request, [FromServices] IExportManager exportManager)
{
    var zipStream = await exportManager.GetUserWorkContext(userId, request.IncludeArchived);
    HttpContext.Response.Headers.Add("Content-Disposition", "attachment; filename = test.zip; charset=Windows-1252");
    HttpContext.Response.Headers.Add("Content-Length", zipStream.ToArray().Length.ToString());
    return File(zipStream.ToArray(), "application/octet-stream");
}

好像不管我怎么下载Javascript(front-end)的文件,都是用utf8编码保存的(又用notepad++找到了)。我尝试使用 js-file-download ( https://www.npmjs.com/package/js-file-download ) 或创建 blob,但我最终下载的任何内容都是用 utf8 编码的。

我应该如何在 Javascript 中下载此文件而不破坏存档?

这是我目前在 Javascript 中的尝试,使用我在此处找到的一段代码 (JavaScript blob filename without link) 下载文件:

function getUserWorkContext({ includeArchived }) {
    return new Promise(function () {
        Axios.post('/api/Export/GetUserWorkContext', {includeArchived})
            .then((response) => {
                if(response.data){
                    var blobObject = new Blob([response.data], {type: 'application/zip;charset=Windows-1252'});
                    downloadFile(blobObject, "test.zip");
                }
            })
}

function downloadFile(file, fileName) {
    if (navigator.msSaveBlob) { // For ie and Edge
        return navigator.msSaveBlob(file, fileName);
    }
    else {
        let link = document.createElement('a');
        link.href = window.URL.createObjectURL(file);
        link.download = fileName;
        document.body.appendChild(link);
        link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
        link.remove();
        window.URL.revokeObjectURL(link.href);
    }
}

注意:实际 zi​​p 为 3,747KB,而从 Javascript 下载的 zip 总是大得多,在本例中为:6,917KB。

这是 axios 的问题:

我猜,你应该使用 blobarraybuffer 作为 axios 的 responseType

{ responseType: 'blob' }

// responseType indicates the type of data that the server will respond with // options are: 'arraybuffer', 'document', 'json', 'text', 'stream' // browser only: 'blob'

responseType: 'json' // default

检查这个答案:https://whosebug.com/a/60461828/2487565

=== 8< =======================以前的版本========== ============= 8< ===

你的Content-Dispositionheader是错误的。 Content-Disposition header.

没有 charset 参数

查看文档:MDN HTTP Content-Disposition

这就是您的文件仍以 UTF-8 格式发送的原因,因为您的 charset 参数无效。

要使用 UTF-8:

删除 C# 中的 Content- headers 和 JavaScript

中的字符集参数
var blobObject = new Blob([response.data], {type: 'application/zip'});

如果确实需要使用Windows-1252,可以尝试用content type参数设置

 return File(zipStream.ToArray(), "application/octet-stream;charset=Windows-1252");

也检查一下:Charset Encoding in ASP.NET Response

顺便说一下,UTF-8 是首选的字符集编码:W3 QA choosing encodings

而且,是的@nikneem,在 Content-DispositionContent-Length header 中没有必要。它们将自动生成。