英文:
Golang stops navigation on downloading
问题
每当我使用Go从我的网站进行大型下载时,它会阻止我在同一浏览器中同时导航或执行其他任何操作。这在Firefox、Chrome和Safari中都会发生,这让我认为这是一个配置问题。
Go环境
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build062753082=/tmp/go-build"
使用默认的GO Web服务器net/http进行此操作。
编辑:
抱歉,忘记了下载的代码
func FunctionName(res http.ResponseWriter, req *http.Request, p httprouter.Params) {
defer req.Body.Close()
setSecurityHeaders(res)
req.ParseForm()
id := p.ByName("id")
incletter, err := GetIncLetterById(bson.ObjectIdHex(id))
if err != nil {
jsonResponse(res, map[string]string{"status": "error", "message": "."})
return
}
bytes, filename := incletter.GetFileBytes()
res.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
res.Header().Set("Content-type", "application/pdf")
res.Header().Set("Content-Length", strconv.Itoa(len(bytes)))
res.Write(bytes)
}
英文:
Whenever I make a large download from my website using Go, it prevents me from navigating or doing anything else in my website in the same browser at the same time the download is happening. This happens with Firefox, chrome and Safari which makes me think it is a conf issue.
Go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build062753082=/tmp/go-build"
Using the default GO Web server net/http for this.
EDIT:
Sorry forgot about the code for the download
func FunctionName(res http.ResponseWriter, req *http.Request, p httprouter.Params) {
defer req.Body.Close()
setSecurityHeaders(res)
req.ParseForm()
id := p.ByName("id")
incletter, err := GetIncLetterById(bson.ObjectIdHex(id))
if err != nil {
jsonResponse(res, map[string]string{"status": "error", "message": "."})
return
}
bytes, filename := incletter.GetFileBytes()
res.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
res.Header().Set("Content-type", "application/pdf")
res.Header().Set("Content-Length", strconv.Itoa(len(bytes)))
res.Write(bytes)
}
答案1
得分: 0
你的头部信息看起来不错(尽管我认为正确的内容类型表示法应该是 proper case(“Content-Type”)。如果这只发生在大文件上,我怀疑这意味着整个文件在传输给客户端之前都被加载到内存中。为了解决这个问题,你可以使用以下代码:
byteSlice, filename := incletter.GetFileBytes()
byteStream := bytes.NewReader(byteSlice)
res.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
res.Header().Set("Content-type", "application/pdf")
res.Header().Set("Content-Length", strconv.Itoa(len(byteSlice)))
io.Copy(res, byteStream)
这将从一个读取器接口直接流式传输到客户端的写入器。
英文:
Your headers look good (Though I think the proper content type notation is proper case ("Content-Type
"). If this is only happening for large files, I suspect this means the entire file is being loaded into memory before being streamed to the client. To get around this, you can use the following:
byteSlice, filename := incletter.GetFileBytes()
byteStream := bytes.NewReader(byteSlice)
res.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
res.Header().Set("Content-type", "application/pdf")
res.Header().Set("Content-Length", strconv.Itoa(len(bytes)))
io.Copy(res, byteStream)
This will essentially stream from a reader interface to a writer directly to the client.
答案2
得分: 0
经过几个小时的困扰后,我联系了我的服务器提供商,原来是他们的问题,他们的带宽有限...谢谢大家。
英文:
After hours of beeing troubled I reached out to my server provider and it was their fault, they had some kind of limited bandwith...
Thanks all
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论