HTTP 文件下载与展示

1,649 阅读2分钟

MIME 类型

媒体类型(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 ),用于表示文件或字节流的类型和格式。

浏览器使用 MIME 类型(而不是文件拓展名)来决定如何处理响应结果,比如当请求响应一张图片时 ,是直接在浏览器打开图片还是将图片保存为文件。

常用 MIME 类型

  • application/octet-stream:表示任意的二进制数据
  • application/json: JSON数据格式
  • text/plain :纯文本格式
  • text/html : HTML格式
  • image/png:png图片格式

Content-Type

Content-Type(内容类型),用于定义响应的内容类型是什么。浏览器会根据 content-type 对响应的内容进行编解码和渲染处理

以下为 firefox 对 json html plain 的处理方式:

image-20211024125538903.png

image-20211024125644227.png

Content-Disposition

Content-Disposition(内容处理方式),用于指示响应的内容该以何种方式处理

  • inline:将内容在浏览器打开展示
  • attachment:将内容作为附件下载到本地
  • attachment; filename:将内容作为附件下载到本地,并指定文件名
1Content-Disposition: inline
2Content-Disposition: attachment
3Content-Disposition: attachment; filename="filename.jpg"

Flask 小文件下载

 1@app.get('/download_bin_file')
 2def index():
 3    display = request.args.get('display')
 4​
 5    filename = 'image.png'
 6    with open(filename, 'rb'as f:
 7        file_content = f.read()
 8​
 9    # 标签页直接展示图片
10    if display == '1':
11        header = {
12            'Content-Type''image/png',
13            'Content-Disposition''inline; filename=' + quote_plus(filename, 'utf-8'),
14        }
1516    # 下载图片
17    if display == '2':
18        header = {
19            'Content-Type''application/octet-stream',
20            'Content-Disposition''attachment; filename=' + quote_plus(filename, 'utf-8'),
21        }
2223    return file_content, 200, header
2425    # 文件路径,作为附件处理,设置附件名
26    # return send_file(filename, as_attachment=True, attachment_filename='12')

Flask 大文件分段下载

大文件响应可使用流式响应,直接使用 send_file 会将整个文件读取到内存中占用过多内存

 1@app.route('/download_big_file')
 2def download_big_file():
 3    def chunk_file():
 4        file_path = 'image.png'
 5        with open(file_path, "rb"as f:
 6            while True:
 7                chunk = f.read(1024 * 1024# 一次读取 1M
 8                if not chunk:
 9                    break
10                yield chunk  # 流式读取
1112    header = {
13        'Content-Type''application/octet-stream',
14        'Content-Disposition''attachment; filename=' + quote_plus('image.png''utf-8'),
15    }
16    return Response(chunk_file(), headers=header)

reference

qrcode_for_gh_c0c4e6d52ae1_344.jpg