Golang在下载时停止导航。

huangapple go评论81阅读模式
英文:

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

huangapple
  • 本文由 发表于 2020年6月2日 03:37:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/62139712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定