响应二进制数据下载

Response binary data to download

我正在尝试从输入字段中输入一个文件,将其临时保存到磁盘并回复 re-download 同一文件。

为此,我了解到我需要使用 content-type : application/octet-streamcontent-disposition: attachment; "filename=myfile.extension" 回复浏览器。

我可以在 /tmp 文件夹中存储和收听我的音乐文件,因此我知道它的输入部分有效。

这是我在金字塔中的代码:

@view_config(route_name='process')
def process_file(request):
    input_file = request.POST['file'].file
    input_file.seek(0)
    file_path = os.path.join('/tmp', '%s.mp3' % uuid.uuid4())
    with open(file_path, 'wb') as output_file:
        shutil.copyfileobj(input_file, output_file)
    print(f"Wrote: {file_path}")
    filename = file_path.split('/')[-1]
    print(filename)
    f = open(file_path, 'rb')
    return Response(body_file=f, charset='UTF-8', content_type='application/octet-stream', content_disposition=f'attachment; "filename={filename}"')

这些是我的回复headers:

这是我的回复body:

但是Chrome/Firefox不要开始下载我的二进制文件。我做错了什么?

更新

我也试过 FileResponse 来自 Pyramid 但没有成功,我仍然没有得到下载弹出窗口。

@view_config(route_name='process')
def process_file(request):
    input_file = request.POST['file'].file
    input_file.seek(0)
    file_path = os.path.join('/tmp', '%s.mp3' % uuid.uuid4())
    with open(file_path, 'wb') as output_file:
        shutil.copyfileobj(input_file, output_file)
    print(f"Wrote: {file_path}")
    return FileResponse(file_path, request=request)

显然我在想如何以错误的方式执行此操作。当我通过 /process 上传文件时,我需要 return 一个 Response('OK') 并向 return 一个 FileResponse 对象发出另一个请求,构建另一个端点 /download 和 returning 文件响应对象解决了这个问题。

示例:

@view_config(route_name='process')
def process_file(request):
    input_file = request.POST['file'].file
    db = request.POST['volume']
    input_file.seek(0)
    filename = '%s.mp3' % uuid.uuid4()
    file_path = os.path.join('/tmp', filename)
    with open(file_path, 'wb') as output_file:
        shutil.copyfileobj(input_file, output_file)
    if boost_track(file_path, filename, db):
        return Response(json_body={'filename': filename})

@view_config(route_name='download')
def download_file(request):
    filename = request.GET['filename']
    file_path = os.path.join('/tmp', filename)
    f = open(file_path, 'rb')
    return Response(body_file=f, charset='UTF-8', content_type='application/download', content_disposition=f'attachment; filename="{filename}"')