为什么Golang将我的POST请求视为GET请求?

4

我的服务器代码如下:

// golang
type SomeHandler struct{}

func (*SomeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    fmt.Println("method:", req.Method)
    fmt.Println("content length:", req.ContentLength)

    // read request body as []byte
    content, err := ioutil.ReadAll(req.Body)
    if err != nil {
        // do sth.
        return
    }

    // decode JSON
    // ...
}

客户端:

// Objective-C on iOS 6/7
// NSURL *myUrl = ...
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:myUrl];
[req setHTTPMethod:@"POST"];
[req setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

id obj = @{
             @"username" : @"myname",
             @"password" : @"mypwd",
          };
NSError *error;
NSData *inputJson = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&error];
if (error) {
    // no error here
}
[req setHTTPBody:inputJson];

[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

    if (error) {
        NSLog(@"ERROR: %@", error.localizedDescription);
        return;
    }

    NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
    NSString *outputText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"response (%d):\n%@", (int)resp.statusCode, outputText);
}

当我在iPhone模拟器上运行这段iOS代码时,服务器端显示:
method: GET
content length: 0

请修改客户端代码:[req setHTTPMethod:@"HEAD"];,服务器将正常工作:

method: HEAD
content length: <some length>

我不知道客户端的POST代码有什么问题,或者服务器应该怎么做才能检索到客户端发送的[]byte数据。请注意,我的Go版本是:

$ go version
go version go1.2.1 darwin/amd64

你确定问题出在Go的一方吗?你尝试过不同的客户端/服务器组合了吗?(例如,使用curl向服务器发出POST请求,或让你的客户端尝试向一个监听netcat套接字进行POST操作) - James Henstridge
我刚刚解决了这个问题。太奇怪了!!检查我的答案。 - Eric Chai
1个回答

8
我来翻译一下这段内容。这是关于IT技术的内容。

我解决了这个问题!行为如此奇怪。我不知道为什么会发生这种情况。

我注册我的处理器如下:

// addr := ...
r := mux.NewRouter()
r.Handle("/abc", new(SomeHandler))
http.Handle("/", r)
// here mux is github.com/gorilla/mux
// these lines of code do the same thing as wrote:
//   http.handle("/abc", new(SomeHandler))

err := http.ListenAndServe(addr, nil)
// ...

然后我的客户端发送一个请求来表明。
http://addr:9999//abc

但正确的URL应该是:
http://addr:9999/abc

调用-stringByAppendingString:方法时生成的冗余斜杠/

3
看起来 gorilla/mux 会自动生成一个重定向响应,以处理非规范化的 URL。HTTP 客户端通常不会因为重定向而重新提交 POST 请求,这可以解释你观察到的行为。 - James Henstridge
是的,有一个新的请求发送到我的服务器。但这不是因为Gorilla/Mux引起的问题。当直接使用net/http编写代码时,例如http.Handle("/abc", new(SomeHandler)),同样的事情也会发生。 - Eric Chai
同样地,我从 http.HandleFunc("/actions/", actionsHandler) 收到了一个意外的 POST 重定向到 GET,解决方法是删除尾随斜杠 http.HandleFunc("/actions", actionsHandler) - jws

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接