Flask Response不支持gb2312编码

问题描述:

做了一个小功能,前端vue点击下载按钮,flask后端返回一个csv文件流(由于项目需要,encoding为gb2312),但是浏览器下载之后发现编码为utf8。

前端代码

downloadTradeList(){
    downloadPositionTradeList({ id: this.$route.query.id }).then(res=>{
      const content = res;
      console.log(res);
      const blob = new Blob([content])
      console.log(blob);
      const fileName = 'tradelist.csv'
      if ('download' in document.createElement('a')) { // 非IE下载
        const elink = document.createElement('a')
        elink.download = fileName
        elink.style.display = 'none'
        elink.href = URL.createObjectURL(blob)
        document.body.appendChild(elink)
        elink.click()
        URL.revokeObjectURL(elink.href) // 释放URL 对象
        document.body.removeChild(elink)
      } else { // IE10+下载
        navigator.msSaveBlob(blob, fileName)
      }
    });
},

后端代码

df = pd.DataFrame(data=orders,columns=columns)
csv_bin_data = df.to_csv(index=False,encoding='gb2312')# (index=True, encoding="utf-8")
response = Response(
    csv_bin_data,
    status=200,
    headers=common_util.generate_download_headers("csv"),
    #mimetype="application/csv",
    mimetype="text/csv",
)
print(type(response.headers),response.headers)
return response

打印信息

werkzeug.datastructures.Headers

Content-Disposition: attachment; filename=20210928_120943.csv
Content-Type: text/csv; charset=utf-8
Content-Length: 1270

问题分析

由打印信息 可将问题定位在后端,虽然csv_bin_data是以gb2312编码,但是header里仍然是utf8。 查看flask的Response源码

原来flask使用的werkzeug.datastructures.Headers类默认编码utf8,并且没有暴露接口供修改。

解决方案

class MyResponse(Response):
    charset = "gb2312"

很简单 将需要其他编码返回的Response用MyResponse代替,问题解决。

posted @ 2021-09-28 12:52  LazyTiming  阅读(105)  评论(0编辑  收藏  举报