如何从HTTP响应读取附件

如何从HTTP响应读取附件,http,go,multipart,Http,Go,Multipart,我正在尝试从URL下载一些csv数据。原始响应如下所示 HTTP/1.1 200 OK Server: Europa-4 X-Varnish: 33948791 Vary: Accept-Encoding, X-UA-Device X-Cache: MISS Cache-Control: no-cache, no-cache, no-store, proxy-revalidate, must-revalidate, max-age=0 Content-Type: application/octe

我正在尝试从URL下载一些csv数据。原始响应如下所示

HTTP/1.1 200 OK
Server: Europa-4
X-Varnish: 33948791
Vary: Accept-Encoding, X-UA-Device
X-Cache: MISS
Cache-Control: no-cache, no-cache, no-store, proxy-revalidate, must-revalidate, max-age=0
Content-Type: application/octet-stream
P3p: CP="CAO PSA OUR"
Date: Fri, 01 Sep 2017 19:53:27 GMT
X-Server: web03
Expires: Fri, 01 Sep 2017 19:53:26 GMT
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked
Accept-Ranges: bytes
X-Content-Type-Options: nosniff
Content-Disposition: attachment; filename="GooglePLAv1US.txt"
Via: 1.1 varnish-v4
Connection: keep-alive
Last-Modified: Fri, 01 Sep 2017 19:53:27 +0000
X-Frame-Options: sameorigin
X-UA-Device: desktop
Age: 0
X-Modified-Url: /amfeed/main/get/file/GooglePLAv1US/?___store=ca_en

id      title   description     google_product_category  .....
20649074       ......
20652632       ......
.
.
.
现在我意识到这不是一个真正的多部分响应,但它有
内容配置:附件;filename=“GooglePLAv1US.txt”
标题,表示需要通过浏览器将其视为下载

当我尝试读取响应体时,它抛出错误
意外的EOF
。我如何读取这些数据,它实际上不在任何一个部分中

代码

http.DefaultClient.Timeout = time.Second * 30
resp, err := http.Get(ht.Creds.AccessData.URL)
if err != nil {
    return nil, err
}
defer resp.Body.Close()
d, err := ioutil.ReadAll(resp.Body)
if err != nil {
    return nil, errors.Wrap(err, "Error reading HTTP response body")
}
这会产生错误

Error reading HTTP response body: unexpected EOF
尝试一下,下面是一个小例子:

package main

import (
    "bufio"
    "fmt"
    "io"
    "net/http"
    "net/http/httptest"
    "net/textproto"
    "os"
)

func main() {
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "%s\n%s\n%s\n%s\n",
            "col1,col2,col3",
            "1,2,3",
            "a,b,c",
            "x,y,x",
        )
    }))
    defer ts.Close()

    client := &http.Client{}
    res, err := client.Get(ts.URL)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    defer res.Body.Close()
    reader := bufio.NewReader(res.Body)
    tp := textproto.NewReader(reader)
    for {
        if line, err := tp.ReadLine(); err != nil {
            if err == io.EOF {
                // if file is emtpy
                return
            }
            return
        } else {
            fmt.Printf("%s\n\n", line)
        }
    }
}

以下是基于您关于“csv”的原始问题的另一个示例:

在这种情况下,请注意
scanner.Split(bufio.ScanBytes)
,希望这能给您带来更多想法。

尝试一下,下面是一个小示例:

package main

import (
    "bufio"
    "fmt"
    "io"
    "net/http"
    "net/http/httptest"
    "net/textproto"
    "os"
)

func main() {
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "%s\n%s\n%s\n%s\n",
            "col1,col2,col3",
            "1,2,3",
            "a,b,c",
            "x,y,x",
        )
    }))
    defer ts.Close()

    client := &http.Client{}
    res, err := client.Get(ts.URL)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    defer res.Body.Close()
    reader := bufio.NewReader(res.Body)
    tp := textproto.NewReader(reader)
    for {
        if line, err := tp.ReadLine(); err != nil {
            if err == io.EOF {
                // if file is emtpy
                return
            }
            return
        } else {
            fmt.Printf("%s\n\n", line)
        }
    }
}

以下是基于您关于“csv”的原始问题的另一个示例:


在这种情况下,请注意
scanner.Split(bufio.ScanBytes)
,希望这能给您提供更多的想法。

在response.Body中,假设您使用的是Go(基于问题标签),但您没有显示任何代码,因此没有任何人可以提供太多帮助。@Adrian提交了我正在使用的代码,谢谢!在response.Body中,假设您使用的是Go(基于问号),但是您没有显示任何代码,因此没有任何人可以提供多少帮助。@Adrian提交了我使用的代码,谢谢!所以有趣的是,如果我检查
err==io,即使我的代码是我的原始代码。errunexpectedof
并忽略它,下载的数据与浏览器下载的数据完全相同有趣的是,如果我检查
err==io,即使是我的原始代码。errunexpectedof
并忽略它,下载的数据与浏览器下载的数据完全相同