如何用Golang上传Content-Type为application/octet-stream的二进制文件?
用Golang实现Content-Type为application/octet-stream的文件上传
你的初始代码核心问题是没有将文件的二进制数据放入请求体,同时存在文件未关闭、错误检查顺序错误的问题,以下是修正后的完整实现:
package main import ( "fmt" "log" "net/http" "net/http/httputil" "os" ) func main() { // 打开目标文件 file, err := os.Open("file.pdf") if err != nil { log.Fatalln("打开文件失败:", err) } defer file.Close() // 确保文件最终关闭,避免资源泄漏 // 获取文件信息,可选:用于设置Content-Length fileInfo, err := file.Stat() if err != nil { log.Fatalln("获取文件信息失败:", err) } // 创建POST请求,直接将文件作为请求体(os.File实现了io.Reader接口) req, err := http.NewRequest("POST", "https://example.com/upload", file) if err != nil { log.Fatalln("创建请求失败:", err) } // 设置Content-Type为application/octet-stream req.Header.Set("Content-Type", "application/octet-stream") // 可选:设置Content-Length,让服务端明确知道请求体大小 req.ContentLength = fileInfo.Size() // 初始化HTTP客户端 client := &http.Client{ Transport: &http.Transport{ DisableCompression: true, }, } // 发送请求 resp, err := client.Do(req) if err != nil { log.Fatalln("发送请求失败:", err) } defer resp.Body.Close() // 打印请求详情(调试用) reqDump, err := httputil.DumpRequest(req, true) if err != nil { log.Fatalln("打印请求失败:", err) } fmt.Println(string(reqDump)) }
关键修改说明
- 将文件作为请求体:
http.NewRequest的第三个参数接受io.Reader类型,os.File天然实现了这个接口,直接传入即可让HTTP包自动读取文件二进制内容作为请求体。 - 错误检查顺序修正:原代码中先设置Header再检查
http.NewRequest的错误,若请求创建失败会导致空指针panic,现在调整为创建请求后立即检查错误。 - 文件资源清理:添加
defer file.Close()确保文件描述符被正确释放。 - Content-Type设置优化:使用
Header.Set而非Add,避免重复添加相同的Header字段。 - 可选的Content-Length设置:通过
file.Stat()获取文件大小后设置req.ContentLength,能让服务端更高效地处理请求,也可以省略,HTTP包会自动通过分块传输编码处理。
内容的提问来源于stack exchange,提问作者smrtsremwsn
相关产品推荐
相关产品推荐

