为什么我不能将一个“文件”作为HTTP请求的“主体”?

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

Why can't I use a "file" as the "body" of an http request?

问题

"http.Post"函数期望将一个"Reader"作为请求体参数。"File"实现了"Reader"接口。但是,如果我将文件作为请求体参数传递,接收方总是会收到0字节的数据。为什么会这样呢?

以下是代码示例:

package main

import (
    "fmt"
    "net/http"
    "os"
)

func main() {
    file, err := os.Open("lala.txt")
    if err != nil {
        fmt.Printf("文件打开错误:%v \n", err)
    }
    defer file.Close()

    resp, err := http.Post("http://requestb.in/11fta851", "text/plain", file)
    if err != nil {
        fmt.Printf("错误:%v \n", err)
    } else {
        fmt.Printf("响应状态码:%d \n", resp.StatusCode)
    }
}

我知道你可以使用"file.ReadAll"将文件读取到缓冲区中并使用它。但这感觉像是重复的工作。

英文:

"http.Post" expects a "Reader" as the body argument. "File" implements "Reader".
But if I pass file as the body argument I always receive 0 bytes at the other end. Why?

Here is the code:

package main

import (
    "fmt"
    "net/http"
    "os"
)

func main() {
    file, err := os.Open("lala.txt")
    if err != nil {
        fmt.Printf("file open errrrr %v \n", err)
    }
    defer file.Close()

    resp, err := http.Post("http://requestb.in/11fta851", "text/plain", file)
    if err != nil {
        fmt.Printf("errrrr %v \n", err)
    } else {
        fmt.Printf("resp code %d \n", resp.StatusCode)
    }
}

I know that you could do "file.ReadAll" to a buffer and use that. But it feels like double work.

答案1

得分: 1

网站requestb.in似乎会忽略POST数据,如果未指定头部Content-Length。以下代码有效:

package main

import (
    "fmt"
    "net/http"
    "os"
)

func main() {
    file, err := os.Open("lala.txt")
    if err != nil {
        fmt.Printf("文件打开错误:%v \n", err)
    }
    defer file.Close()

    req, _ := http.NewRequest("POST", "http://requestb.in/1fry3jy1", file)
    req.ContentLength = 5
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Printf("错误:%v \n", err)
    } else {
        fmt.Printf("响应代码:%d \n", resp.StatusCode)
    }
}

希望这对你有帮助!

英文:

The site requestb.in seems to ignore POST data if the header Content-Length is not specified. This code works:

package main

import (
    "fmt"
    "net/http"
    "os"
)

func main() {
    file, err := os.Open("lala.txt")
    if err != nil {
        fmt.Printf("file open errrrr %v \n", err)
    }
    defer file.Close()

    req, _ := http.NewRequest("POST", "http://requestb.in/1fry3jy1", file)
    req.ContentLength = 5
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Printf("errrrr %v \n", err)
    } else {
        fmt.Printf("resp code %d \n", resp.StatusCode)
    }
}

huangapple
  • 本文由 发表于 2015年7月27日 17:52:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/31649989.html
匿名

发表评论

匿名网友

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

确定