[英]How can I let a user download a file from an s3 bucket when clicking on a button?
[英]How to let user download file while it's being generated
我想让用户在尚未准备就绪时开始下载文件。 我不想将用户发送到某个页面,说“等待30秒,文件正在准备中”。 我无法提前生成文件。 我需要用户点击/发送表格,选择下载位置并开始下载。 生成的文件将是zip,所以我想,应该可以使用拉链的前几个字节(总是相同的)发送文件名,并且在生成文件之前不确认tcp包是否正确发送或类似那,并在生成文件后发送其余的。
我怎么做? 有没有任何工具可以做到这一点。 还是有更好的方法吗? 更高级别的解决方案更好,C不是我的强项。 最好是在Python中。 谢谢。
正在生成的文件是zip,在准备好之前,还没有任何东西可以发送。 基本上根据输入我生成一组文件(这需要几十秒),而不是我压缩它们并为用户服务。 我的应用程序是在Linux上的python中,但我将使用哪个服务器并不重要。
文件准备好后,客户端很可能会超时(或等待30秒而不通知)。 我会使用流压缩算法(gzip)来压缩文件在传输过程中。 这不会导致最佳压缩,但会以可预测的方式提供文件。
调查“Content-Encoding:gzip”HTTP标头。
通常,像这样的应用程序将分两部分实现,例如票务系统。
当用户单击/提交表单时,表单将向服务发送请求,该服务将开始生成文件作为后台进程,然后(无需等待文件生成)它将生成表示新文件的票证/哈希然后将用户重定向到新的URL,例如/files/<random-hash>
在这个新的URL /files/<random-hash>
,当文件没有准备好时,它将返回一个简单的HTML页面,向用户显示要等待的消息,并在页面上有一个脚本,将继续刷新页面每隔几秒钟。 只要文件没有准备好,它就会继续显示此消息,但是一旦文件准备就绪,该URL将返回其响应中的实际文件内容,而不是相应的mime-header。
使用数据库和一些编程实现该解决方案非常简单。 但是,如果你正在寻找一个已经准备好使用的工具,我很抱歉我不熟悉它。 希望这有帮助。
尽管声称这是不可能的,但我设法找到了办法。 我在此期间学到了一些Go,所以我使用了它,但我猜它在其他语言中不会有太大的不同。
基本上第一个字节写在writer中然后刷新。 浏览器比等待休息。
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
)
func Zip(w http.ResponseWriter, r *http.Request) {
file_name := r.URL.Path
file_name = strings.TrimPrefix(file_name, "/files/")
w.Header().Set("Content-type", "application/zip")
w.Write([]byte{80})
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
for {
if _, err := os.Stat("./files/" + file_name); err == nil {
fmt.Println("file found, breaking")
break
}
time.Sleep(time.Second)
}
stream_file_bytes, err := ioutil.ReadFile("./files/" + file_name)
if err != nil {
fmt.Println(err)
return
}
b := bytes.NewBuffer(stream_file_bytes)
b.Next(1)
b.WriteTo(w)
fmt.Println("end")
}
func main() {
http.HandleFunc("/files/", Zip)
if err := http.ListenAndServe(":8090", nil); err != nil {
panic(err)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.