如何使用 Swag golang 库下载文件?
How to download files using Swag golang library?
我正在尝试使用 golang[=] 中的 gin-gonic 创建一个 REST API 36=],它从 GET 请求和 下载 该文件中获取一些路径参数。
curl 命令可以正常工作。
但是,当我添加 swagger UI 文档时,如果下载的文件是文本或图像,它只是显示在该网页中,但我看不到任何下载选项.此外,如果我输入视频文件的路径,浏览器会挂起。
此外,要下载的文件的 MIME 类型由 gin-gonic 正确确定。但是,要通过 swagger UI 接口 下载文件,我使用的是硬编码 @Accept & @Produce swagger UI 评论注释。理想情况下,它应该自动确定 MIME 类型。
目前,响应类型列为下拉列表,我可以在其中获得各种选项。
我需要它来自动检测正确的 MIME 类型并在可能的情况下显示 下载 按钮
我的 GET 请求代码是:
// DownloadObject godoc
// @Summary Download object
// @Description Download object
// @Produce application/json
// @Produce text/plain
// @Produce application/octet-stream
// @Produce video/mp4
// @Produce image/png
// @Produce image/jpeg
// @Produce image/gif
// @Param rootPath path string true "Root Path"
// @Param filePath path string true "File Path"
// @Header 200 {string} Token "qwerty"
// @Router /transfer/{rootPath}/{filePath} [get]
func DownloadObject(c *gin.Context) {
// Get rootPath & filePath from GET request
rootPath := c.Param("rootPath")
filePath := c.Param("filePath")
// Some code to get an io.Reader object "download"
_, err = io.Copy(c.Writer, download)
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
err = download.Close()
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%", filePath))
c.Writer.Header().Add("Content-Type", c.GetHeader("Content-Type"))
// Object download completed & closed successfully
}
我是不是漏掉了什么?
您要在浏览器收到文件后添加 headers,将它们移到 io.Copy
之前才能生效。此外,您在 fmt.Sprintf
调用中有一个错误的格式动词(只是 %
),请使用 %q
:
func DownloadObject(c *gin.Context) {
// Get rootPath & filePath from GET request
rootPath := c.Param("rootPath")
filePath := c.Param("filePath")
// ...
// Add headers to the response
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%q", filePath))
c.Writer.Header().Add("Content-Type", c.GetHeader("Content-Type"))
_, err = io.Copy(c.Writer, download)
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
err = download.Close()
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
}
我正在尝试使用 golang[=] 中的 gin-gonic 创建一个 REST API 36=],它从 GET 请求和 下载 该文件中获取一些路径参数。
curl 命令可以正常工作。 但是,当我添加 swagger UI 文档时,如果下载的文件是文本或图像,它只是显示在该网页中,但我看不到任何下载选项.此外,如果我输入视频文件的路径,浏览器会挂起。
此外,要下载的文件的 MIME 类型由 gin-gonic 正确确定。但是,要通过 swagger UI 接口 下载文件,我使用的是硬编码 @Accept & @Produce swagger UI 评论注释。理想情况下,它应该自动确定 MIME 类型。
目前,响应类型列为下拉列表,我可以在其中获得各种选项。 我需要它来自动检测正确的 MIME 类型并在可能的情况下显示 下载 按钮
我的 GET 请求代码是:
// DownloadObject godoc
// @Summary Download object
// @Description Download object
// @Produce application/json
// @Produce text/plain
// @Produce application/octet-stream
// @Produce video/mp4
// @Produce image/png
// @Produce image/jpeg
// @Produce image/gif
// @Param rootPath path string true "Root Path"
// @Param filePath path string true "File Path"
// @Header 200 {string} Token "qwerty"
// @Router /transfer/{rootPath}/{filePath} [get]
func DownloadObject(c *gin.Context) {
// Get rootPath & filePath from GET request
rootPath := c.Param("rootPath")
filePath := c.Param("filePath")
// Some code to get an io.Reader object "download"
_, err = io.Copy(c.Writer, download)
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
err = download.Close()
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%", filePath))
c.Writer.Header().Add("Content-Type", c.GetHeader("Content-Type"))
// Object download completed & closed successfully
}
我是不是漏掉了什么?
您要在浏览器收到文件后添加 headers,将它们移到 io.Copy
之前才能生效。此外,您在 fmt.Sprintf
调用中有一个错误的格式动词(只是 %
),请使用 %q
:
func DownloadObject(c *gin.Context) {
// Get rootPath & filePath from GET request
rootPath := c.Param("rootPath")
filePath := c.Param("filePath")
// ...
// Add headers to the response
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%q", filePath))
c.Writer.Header().Add("Content-Type", c.GetHeader("Content-Type"))
_, err = io.Copy(c.Writer, download)
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
err = download.Close()
if err != nil {
c.Status(http.StatusInternalServerError)
log.Print(err)
return
}
}