响应二进制数据下载
Response binary data to download
我正在尝试从输入字段中输入一个文件,将其临时保存到磁盘并回复 re-download 同一文件。
为此,我了解到我需要使用 content-type : application/octet-stream
和 content-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}"')
我正在尝试从输入字段中输入一个文件,将其临时保存到磁盘并回复 re-download 同一文件。
为此,我了解到我需要使用 content-type : application/octet-stream
和 content-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}"')