【问题标题】:Downloaded compressed data (`gz`) from django server using ajax is inflated and broken使用 ajax 从 django 服务器下载的压缩数据 (`gz`) 被夸大和损坏
【发布时间】:2019-11-21 04:22:51
【问题描述】:

我正在尝试使用 Ajax 发布请求从 django 服务器 (Python 3.7) 下载 .gz 文件。这是在客户端请求下载、压缩文件夹并发送(服务器)并在客户端接收数据的最小 django 视图函数和 Ajax 函数:

from pathlib import Path 

def downloadfile(request):
    folder = Path().home().joinpath('workspace')
    tar_path =  Path().home().joinpath('workspace.gz')
    tar = tarfile.open(tar_path.as_posix(), 'w:gz')
    tar.add(folder.as_posix(), arcname='workspace')
    tar.close()

    try:
        with open(tar_path.as_posix(), 'rb') as f:
            file_data = f.read()
        response = HttpResponse(file_data, content_type='application/gzip')
        response['Content-Disposition'] = 'attachment; filename="workspace.gz"'
    except IOError:
        response = HttpResponse('File not exist')

    return response

这是客户端的Ajax功能:

$(function () {
    $('#downloadfile').submit(function () {
        $.ajax({
            type: 'POST',
            url: 'downloadfile',
            success: function(response){
                download(response,'workspace.gz', 'application/gzip');
            }
        });
        return false;
    });
});

function download(content, filename, contentType)
{
    var a = document.createElement('a');
    var blob = new Blob([content], {'type':contentType});
    a.href = window.URL.createObjectURL(blob);
    a.download = filename;
    a.click();
}

一个 36.5 KB 的示例 gzip 文件夹在下载时会膨胀到 66.1 KB,并且显然无法提取。

我知道的:

  • 文件运行状况良好,可在服务器端提取。
  • 数据在客户端传输和下载,但膨胀和损坏。
  • JavaScript 函数中的 respone 变量看起来像二进制数据(没有任何标题)

我不知道的:

  • 为什么即使我以二进制格式读取和发送压缩文件并且两种内容类型都设置为'application/gzip',但数据大小却增加了?
  • 如果向文件中添加了某些内容,它是什么以及何时添加?

谢谢你,

【问题讨论】:

    标签: django ajax


    【解决方案1】:

    在这上面花了几个小时后,以下对我有用。

    诀窍是在 Django 视图部分使用hexify。 Django 视图中的发送部分应该是:

    try:
        with open(tar_path.as_posix(), 'rb') as f:
            file_data = binascii.hexlify(f.read())
        response = HttpResponse(str(file_data), content_type='application/gzip')
        response['Content-Disposition'] = 'attachment; filename="%s"' % userid
        os.remove(tar_path.as_posix())
    except IOError:
        response = HttpResponse('File not exist')
    
    return response
    

    并且 JS 部分应该创建一个字节数组:

    var r = response.substring(2, response.length - 1);
    var typedArray = new Uint8Array(r.match(/[\da-f]{2}/gi).map(function (h) {
        return parseInt(h, 16)
    }));
    download(typedArray, 'workspace.tar.gz', 'application/gzip');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多