将数据输出到CSV文件时,数据会显示在浏览器上,但不会被写入文件。

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

Output to csv file dumps the data to browser but not dump to file

问题

我在beego框架中尝试将一些数据输出到CSV文件,以下是我的代码:

records := make([][]string, len(devicesData))

for k, v := range devicesData {
    records[k] = []string{v.Fields.Country, v.Fields.Imei[0], v.Fields.Number[0]}
}

writer := csv.NewWriter(this.Controller.Ctx.ResponseWriter)
for _, record := range records {
    err := writer.Write(record)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
}

this.Ctx.Output.Header("Content-Type", "application/csv")
this.Ctx.Output.Header("Content-Disposition", "attachment; filename=MyVerySpecial.csv")

writer.Flush()

然而,它只在浏览器中显示记录数据,无法下载文件。在下载文件控制器之前,我有一些日志控制器和过滤器函数,我不知道它是否受到影响。我的代码有什么问题?谢谢。

英文:

I tried to ouput some data to csv file in golang beego framework, here is my code

records := make([][]string,len(devicesData))

for k,v := range devicesData{
	records[k] = []string{v.Fields.Country,v.Fields.Imei[0],v.Fields.Number[0]}
}

writer := csv.NewWriter(this.Controller.Ctx.ResponseWriter)
for _, record := range records {
	err := writer.Write(record)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
}

this.Ctx.Output.Header("Content-Type", "application/csv")
this.Ctx.Output.Header("Content-Disposition", "attachment; filename=MyVerySpecial.csv")

 	writer.Flush()

However, it only shows the record data in browser, it cannot download the file. I have some loging controller and filter function before this download file controller, I do not whether it is affected. What's wrong with my code? Thanks

答案1

得分: 3

你应该始终首先设置响应头,然后再开始写入任何数据到输出流。我知道你在设置头字段后调用了writer.Flush(),但这并不能保证数据在此之前不会被刷新或发送,这将意味着默认的头部将被发送。在此之后,不能发送或更改额外的头部。

此外,CSV的正确媒体类型是text/csv,而不是application/csvrfc4180)。

另外,头部更像是对浏览器的一个“建议”。你建议响应是一个要保存的文件,但从服务器端来看,你不能强制浏览器真正将响应保存为文件而不是显示它。

有关"Content-Disposition"头字段的更多详细信息,请参阅rfc1806rfc2183rfc6266。基本上,它传达了展示信息。

"Content-Disposition"响应头字段用于传达有关如何处理响应有效载荷的附加信息,还可以用于附加元数据,例如在本地保存响应有效载荷时要使用的文件名。

英文:

You should always set response headers first and only after that start writing any data to the output. I know you called writer.Flush() after setting header fields, but that is no guarantee whatsoever that data will not be flushed or sent before that - which will imply default headers being sent. After this no additional headers can be sent or changed.

Also the proper mime type for CSV is text/csv not application/csv (rfc4180).

Also the headers are more like a "proposal" to the browser. That's one thing you suggest the response is a file to be saved, but from the server side you can't force the browser to really save the response to a file and not display it.

See rfc1806, rfc2183 and rfc6266 for more details about the "Content-Disposition" header field. Basically it communicates presentation information.

> The Content-Disposition response header field is used to convey
additional information about how to process the response payload, and
also can be used to attach additional metadata, such as the filename
to use when saving the response payload locally.

huangapple
  • 本文由 发表于 2015年6月24日 13:06:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/31018042.html
匿名

发表评论

匿名网友

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

确定