【问题标题】:Download ANSI zip file in front end, generated by C# back end在前端下载ANSI zip文件,由C#后端生成
【发布时间】:2021-02-12 02:21:36
【问题描述】:

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

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

[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(前端)下载文件,它都以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。

【问题讨论】:

  • 您是否尝试删除标头 Content-Disposition 和 Content-Length?它们对我来说似乎是多余的......
  • @nikneem 是的,我有,我尝试返回 return File(zipStream.ToArray(), "application/octet-stream");并返回 File(zipStream.ToArray(), "application/octet-stream", "test.zip");没有设置标题,这两个都不起作用
  • 我相信,你不需要转换你的zipStream.ToArray()。它适用于流File(zipStream, "application/octet-stream", "test.zip");
  • 好主意@Tolbxela,但它似乎并没有改变结果。
  • @barbo 请检查我的更新答案。

标签: javascript c# encoding axios zip


【解决方案1】:

这是 axios 的问题:

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

{ responseType: 'blob' }

// responseType 表示服务器将要发送的数据类型 响应 // 选项有:'arraybuffer'、'document'、'json'、 'text', 'stream' // 仅限浏览器:'blob'

responseType: 'json' // 默认

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

=== 8

您的 Content-Disposition 标头错误。 Content-Disposition 标头没有 charset 参数。

查看文档:MDN HTTP Content-Disposition

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

使用 UTF-8:

从 C# 中删除 Content- 标头和从 JavaScript 中删除字符集参数

var blobObject = new Blob([response.data], {type: 'application/zip'});

如果确实需要使用Windows-1252,可以尝试使用内容类型参数进行设置。

 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 标头中不需要。它们将自动生成。

【讨论】:

  • 嗨!内容类型不会改变结果。我认为问题更多在于文件在前端下载的方式,因为它始终默认为 utf8。用于创建 blob 的 response.data 只是一个字符串,没有关于那里使用的内容类型的信息......
  • 我想使用 UTF8,但我还没有找到一种方法来创建以 UTF8 编码的存档。这确实会简化很多事情
  • 您不需要以 UTF8 编码存档。只需从您的 js var blobObject = new Blob([response.data], {type: 'application/zip'}); 中删除 charset 参数
  • filename*=UTF-8''test.zip UTF-8 是文件名的编码,而不是 zip 存档的编码!
  • 别管我的最后一个问题,添加 responseType 解决了这一切!非常感谢!
猜你喜欢
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
  • 1970-01-01
  • 2020-05-28
  • 2014-10-10
  • 2018-09-05
  • 2021-10-02
相关资源
最近更新 更多