golang gin static 强制以文件方式下载

文章目录

    用 golang gin static 实现了一个文件下载功能,同时下载前需要先鉴权。例如:

    // serve /download under a group that enforces token validation
    g := r.Group("/download")
    g.Use(DownloadAuthMiddleware())
    g.Static("/", downloadPath)
    

    DownloadAuthMiddleware 是一个中间件,会判断文件下载链接中的 token 参数是否过期。

    这个加载功能,在本地开发环境是一切正常的,但是到了线上,套上 cloudflare 之后,就出现了问题。例如:

    下载一个 csv 的文件,本地浏览器打开,会自动触发浏览器的另存为的方式。
    但是到了线上,变成了直接展示 csv 文件内容,变成了一个网页展示。

    而且,下载链接如果直接右键保存,下载下来的 csv 文件名后缀,会被自动替换成了 txt 后缀。

    HTTP 头对比

    本地的 http 头

    本地的 http 头

    线上的 cloudflare http 头

    线上的 cloudflare http 头

    会看到 cloudflare http 头没有 content type …

    添加 Content-Disposition 头信息

    按照 AI 的提示,在中间件中添加了 Content-Disposition 头信息。如下:

    // 强制下载
    c.Header("Content-Disposition", "attachment; filename=\""+url.PathEscape(reqPath)+"\"")
    

    Content-Disposition 是一个 HTTP 响应头(也可用于 MIME 邮件),主要作用是指示客户端如何处理响应内容,特别是控制文件的下载行为。

    • 强制下载文件。例如:Content-Disposition: attachment; filename=“example.pdf”
    • 内联显示。例如:Content-Disposition: inline; filename=“photo.jpg”

    添加之后,线上的下载行为也正常了。

    content type 依旧不对

    本地环境,会看到多了 Content-Disposition 头,其他头也是正常的。

    本地环境,会看到多了 Content-Disposition 头

    cloudflare 返回头,虽然多了 Content-Disposition 头,下载文件的扩展名正确了。但是 content type 依旧不对:

    cloudflare 返回头多了 Content-Disposition 头

    先不管了,目前功能正常了就行,后面遇到问题再优化。

    DeepSeek 的观点是,最常见的罪魁祸首是 Cloudflare 的缓存规则和优化功能覆盖了原始响应头。建议先关闭所有优化功能测试,然后逐个开启定位问题。

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式