有一个需求是这样的:
需要用go从一个接口获取pdf文件,然后前端js向go请求这个pdf文件,最终在页面上显示一个预览按钮并可以点击预览pdf
前端 → go → pdf
具体是这么一个过程,pdf用二进制方式传递,具体如何实现呢。。?
有一个需求是这样的:
需要用go从一个接口获取pdf文件,然后前端js向go请求这个pdf文件,最终在页面上显示一个预览按钮并可以点击预览pdf
前端 → go → pdf
具体是这么一个过程,pdf用二进制方式传递,具体如何实现呢。。?
根据 @loxp 的回答,写了测试代码。完全可行
func main() {
http.HandleFunc("/index", IndexHandler)
http.ListenAndServe(":8082", nil)
}
func IndexHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/pdf")
f, err := os.OpenFile("./go_book.pdf", os.O_RDONLY, 0777)
if err != nil {
// handle the error
}
defer f.Close()
io.Copy(w, f)
//b, err := ioutil.ReadAll(f)
//if err != nil {
// panic(err)
//}
//w.Write(b)
}
访问http://127.0.0.1:8082/index
就可以看到效果
w.Header().Add("Content-Type", "application/pdf")
w.Header().Add("Content-Disposition", "attachment; filename=\""+fileNames+"\"")
经测试只设置 Content-Type即可,w.Header().Add("Content-Transfer-Encoding", "binary") 不是必须的,详情 https://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html
用 http.ServeFile() 也可实现下载显示
package main
import (
"log"
"net/http" "os" "time")
func main() {
http.HandleFunc("/", zipHandler)
log.Println("Listening......")
http.ListenAndServe(":8080", nil)
}
func zipHandler(rw http.ResponseWriter, r \*http.Request) {
rw.Header().Set("Content-Type", "application/pdf")
f, err := os.Open("./sample.pdf");
defer f.Close()
if err == nil {
for {
buf := make(\[\]byte, 1024)
\_, err := f.Read(buf);
if err == nil {
rw.Write(buf)
// 流控
time.Sleep(1000 \* time.Microsecond)
} else {
return
}
}
}
}
2 回答2.7k 阅读✓ 已解决
1 回答2.4k 阅读✓ 已解决
2 回答1.8k 阅读✓ 已解决
1 回答1.3k 阅读✓ 已解决
1 回答1.5k 阅读✓ 已解决
2 回答1.4k 阅读
1 回答1.9k 阅读
楼上的如果PDF过大,一次性读取会有内存问题。
另外,不要使用
panic
来中断逻辑运行,一旦panic没被处理,整个程序挂掉