我有一个应用程序,用户可以批量下载图像。客户端使用一些文件ID发出一个post请求,服务器获取文件名,然后遍历文件名,获取它们并写入zip。
压缩本身很好(通过使用os.Create检查实际文件并检查它来验证),但我也试图避免保存生成的zip文件,而是通过使用io直接将其作为响应流式传输到浏览器.Copy。
func (c *controller) GetZipped(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
...
files, err := services.FetchImageFileNames(imageIds, id, imgC.db)
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
zipName := time.Now().Format("2006-01-02") + ".zip"
w.Header().Add("Content-Disposition", "attachment; filename=\""+zipName+"\"")
w.Header().Add("Content-Type", "application/zip")
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
zipWriter := zip.NewWriter(w)
zipWriter.Flush()
// Loop over files, fetch the image and add to zip
for _, file := range files {
resp, err := http.Get(c.rcUrl + file)
if err != nil {
continue
}
defer resp.Body.Close()
h := &zip.FileHeader{Name: file, Method: zip.Deflate}
f, err := zipWriter.CreateHeader(h)
if err != nil {
continue
}
io.Copy(f, resp.Body)
resp.Body.Close()
}
zipWriter.Close()
}
在Chrome开发工具中,我看到此请求的响应是在流式传输时接收数据,但文件未下载并保存在任何位置。
我希望避免保存zip文件并直接将文件流式传输,这样我们就可以避免进行任何清理。
这是浏览器无法识别内容处置的问题吗? 我也尝试了各种内容类型(八位字节流等),但仍然没有运气。
我用它作为指南: https://engineroom.teamwork.com/how-to-securely-provide-a-zip-download-of-a-s3-file-bundle/
非常感谢任何帮助!