【问题标题】:Golang http.NewRequest always returns 404 - Postman okGolang http.NewRequest 总是返回 404 - Postman ok
【发布时间】:2019-06-20 07:55:05
【问题描述】:

我正在尝试编写一个发布请求函数,该函数将文件从 golang 服务器发送到客户端。代码是从这里 (golang POST data using the Content-Type multipart/form-data) 抄录下来的。无论出于何种原因,我总是得到“404 page not found”,即使通过邮递员完成的相同请求正在命中 endpt 并成功返回。这是一种奇怪的行为,我不太确定如何调试。 (出于测试目的,我对 URL 进行了硬编码以访问本地运行的服务器。)

这是我的代码:

func PostUpload(values map[string]io.Reader, URL string){
    fmt.Println("inside PostUpload in outbound")
    client := &http.Client{}
    var err error

    var b bytes.Buffer
    w := multipart.NewWriter(&b)
    for key, r := range values {
            var fw io.Writer
            if x, ok := r.(io.Closer); ok {
                    defer x.Close()
            }
            // Add an image file
            if x, ok := r.(*os.File); ok {
                    if fw, err = w.CreateFormFile(key, x.Name()); err != nil {
                            return
                    }
            } else {
                    // Add other fields
                    if fw, err = w.CreateFormField(key); err != nil {
                            return
                    }
            }
            if _, err = io.Copy(fw, r); err != nil {
                fmt.Println("there was an error")
                fmt.Println(err)
            }
        }
    w.Close()

    // Now that you have a form, you can submit it to your handler.
        // req, err := http.NewRequest("POST", URL, &b)
        req, err := http.NewRequest("POST", "http://127.0.0.1:5000/upload", &b)
    if err != nil {
                fmt.Println("there was an error on http.NewRequest in outbound post file upload")
                fmt.Println(err)
    }
    // Don't forget to set the content type, this will contain the boundary.
        req.Header.Set("Content-Type", w.FormDataContentType())


        requestDump, err := httputil.DumpRequest(req, true)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(string(requestDump))


    // Submit the request
    resp, err := client.Do(req)
    if err != nil {
                fmt.Println("there was an error on client do in outbound post file upload")
                fmt.Println(err)
        }

        resp_body, _ := ioutil.ReadAll(resp.Body)
        var parsed map[string]interface{}
        err = json.Unmarshal(resp_body, &parsed)
        if err!=nil{
            if typeof(resp_body)=="[]uint8"{
                fmt.Println("received []uint8, converting and displaying")
                fmt.Print(string(resp_body))
            }else{
                fmt.Println("inside unmarshal error")
                fmt.Println(err)
            }
        }

    return
}

这是控制台的输出:

api      | 21:16:09 app         | inside PostUpload in outbound
api      | 21:16:09 app         | POST /upload HTTP/1.1
api      | Host: 127.0.0.1:5000
api      | Content-Type: multipart/form-data; boundary=0ce8aee17e5d00524acd3875d8b4b41dba5f99d8a7796d56289e38f89c64
api      |
api      | --0ce8aee17e5d00524acd3875d8b4b41dba5f99d8a7796d56289e38f89c64
api      | Content-Disposition: form-data; name="file"; filename="/uploads/TIME^2019-01-26 21:16:09.413514444 +0000 UTCFILE^Any_Publishing.txt"
api      | Content-Type: application/octet-stream
api      |
api      | # © 2016 and later: Unicode, Inc. and others.
api      | # License & terms of use: http://www.unicode.org/copyright.html#License
api      | #
api      | # File: Any_Publishing.txt
api      | # Generated from CLDR
api      | #
api      |
api      | # Variables
api      | $single = \' ;
api      | $space = ' ' ;
api      | $double = \";
api      | $back = \` ;
api      |
api      | --0ce8aee17e5d00524acd3875d8b4b41dba5f99d8a7796d56289e38f89c64--
api      |
api      | 21:16:09 app         | received []uint8, converting and displaying
api      | 404 page not found

有人知道出了什么问题吗?

编辑:

有人建议注释掉 req 上的转储,因为它可能会消耗 req 并将其留空以进行请求。我试过了,结果和上面一样。

有人提到他们想看到成功上传的 curl 请求,所以这里是:

patientplatypus:~/Downloads:15:48:28$curl -X POST -F "file=@./catpic.jpg" http://127.0.0.1:5000/upload
file uploaded successfully!

带有 -v 标志的 curl 的完整转储:

patientplatypus:~/Downloads:15:48:42$curl -v -X POST -F "file=@./catpic.jpg" http://127.0.0.1:5000/upload
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> POST /upload HTTP/1.1
> Host: 127.0.0.1:5000
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 264915
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------48411aa948b523e2
>
< HTTP/1.1 100 Continue
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/html; charset=utf-8
< Content-Length: 27
< Server: Werkzeug/0.14.1 Python/3.6.5
< Date: Sat, 26 Jan 2019 22:12:19 GMT
<
* Closing connection 0
file uploaded successfully!

有人提到他们想查看我试图访问的服务器,所以这里是:https://github.com/patientplatypus/pythonServer

【问题讨论】:

    标签: go file-upload server upload http-status-code-404


    【解决方案1】:

    那个 404 错误字符串看起来和 Go 标准库生成的一样:

    你确定你真的在使用 Flask 应用程序吗?

    【讨论】:

    • 当我们谈到这个问题时,我在 docker-compose 中隐藏了我的端口:5000。上网点给你!
    • 我在调试数小时后修复,我只是在方法字符串上使用了大写字符。即:post -> POST
    【解决方案2】:

    从外观上看,您并没有提出相同的要求。卷曲(感谢包含它)设置一个表单值,而你的 go 设置 2。在你的 curl 中它是“文件”,但在 go 中是“文件名”。我在输出的内容配置行中看到了这一点。带有 -v 的卷曲还可能包含有关它发送 f 的更多信息。

    【讨论】:

    • 我认为这在文件名部分实际上可能没问题 - 最坏的情况是它应该到达 endpt,然后在尝试读取文件后反弹,但我什至不明白。上面详细程度的卷曲输出。
    猜你喜欢
    • 2015-01-04
    • 2022-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 2015-07-31
    • 1970-01-01
    • 2019-10-29
    • 2016-02-04
    相关资源
    最近更新 更多