为什么 Golang 将我的 POST 请求当作 GET 请求处理?

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

Why Golang treats my POST request as a GET one?

问题

我的服务器代码如下:

  1. // golang
  2. type SomeHandler struct{}
  3. func (*SomeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
  4. fmt.Println("method:", req.Method)
  5. fmt.Println("content length:", req.ContentLength)
  6. // read request body as []byte
  7. content, err := ioutil.ReadAll(req.Body)
  8. if err != nil {
  9. // do sth.
  10. return
  11. }
  12. // decode JSON
  13. // ...
  14. }

客户端代码如下:

  1. // Objective-C on iOS 6/7
  2. // NSURL *myUrl = ...
  3. NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:myUrl];
  4. [req setHTTPMethod:@"POST"];
  5. [req setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
  6. id obj = @{
  7. @"username" : @"myname",
  8. @"password" : @"mypwd",
  9. };
  10. NSError *error;
  11. NSData *inputJson = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&error];
  12. if (error) {
  13. // no error here
  14. }
  15. [req setHTTPBody:inputJson];
  16. [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue]
  17. completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  18. if (error) {
  19. NSLog(@"ERROR: %@", error.localizedDescription);
  20. return;
  21. }
  22. NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
  23. NSString *outputText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  24. NSLog(@"response (%d):\n%@", (int)resp.statusCode, outputText);
  25. }];

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

  1. method: GET
  2. content length: 0

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

  1. method: HEAD
  2. content length: <some length>

我不知道客户端的 POST 代码有什么问题,或者服务器端应该如何获取客户端发送的数据作为 []byte

另外,我的 Go 版本是:

  1. $ go version
  2. go version go1.2.1 darwin/amd64
英文:

My server code like:

  1. // golang
  2. type SomeHandler struct{}
  3. func (*SomeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
  4. fmt.Println(&quot;method:&quot;, req.Method)
  5. fmt.Println(&quot;content length:&quot;, req.ContentLength)
  6. // read request body as []byte
  7. content, err := ioutil.ReadAll(req.Body)
  8. if err != nil {
  9. // do sth.
  10. return
  11. }
  12. // decode JSON
  13. // ...
  14. }

Client side:

  1. // Objective-C on iOS 6/7
  2. // NSURL *myUrl = ...
  3. NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:myUrl];
  4. [req setHTTPMethod:@&quot;POST&quot;];
  5. [req setValue:@&quot;application/json; charset=utf-8&quot; forHTTPHeaderField:@&quot;Content-Type&quot;];
  6. id obj = @{
  7. @&quot;username&quot; : @&quot;myname&quot;,
  8. @&quot;password&quot; : @&quot;mypwd&quot;,
  9. };
  10. NSError *error;
  11. NSData *inputJson = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&amp;error];
  12. if (error) {
  13. // no error here
  14. }
  15. [req setHTTPBody:inputJson];
  16. [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue]
  17. completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  18. if (error) {
  19. NSLog(@&quot;ERROR: %@&quot;, error.localizedDescription);
  20. return;
  21. }
  22. NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
  23. NSString *outputText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  24. NSLog(@&quot;response (%d):\n%@&quot;, (int)resp.statusCode, outputText);
  25. }

When I run this iOS code in iPhone simulator the server side shows:

  1. method: GET
  2. content length: 0

Chage my client side code: [req setHTTPMethod:@&quot;HEAD&quot;];, the server works:

  1. method: HEAD
  2. content length: &lt;some length&gt;

I don't know what's wrong with my POST code on the client or what should I do on the server to retrieve data as []byte my client just sent.

btw,
my go version:

  1. $ go version
  2. go version go1.2.1 darwin/amd64

答案1

得分: 8

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

我注册了我的处理程序,像这样:

  1. // addr := ...
  2. r := mux.NewRouter()
  3. r.Handle("/abc", new(SomeHandler))
  4. http.Handle("/", r)
  5. // 这里的mux是github.com/gorilla/mux
  6. // 这些代码行与下面的代码行做的事情是一样的:
  7. // http.handle("/abc", new(SomeHandler))
  8. err := http.ListenAndServe(addr, nil)
  9. // ...

然后我的客户端发送了一个请求,说

  1. http://addr:9999//abc

但正确的URL应该是

  1. http://addr:9999/abc

在调用-stringByAppendingString:方法时产生了多余的/

英文:

I solved this! So strange behavior. I don't know why this could happen.

I register my handler like:

  1. // addr := ...
  2. r := mux.NewRouter()
  3. r.Handle(&quot;/abc&quot;, new(SomeHandler))
  4. http.Handle(&quot;/&quot;, r)
  5. // here mux is github.com/gorilla/mux
  6. // these lines of code do the same thing as wrote:
  7. // http.handle(&quot;/abc&quot;, new(SomeHandler))
  8. err := http.ListenAndServe(addr, nil)
  9. // ...

Then my client sends a request to say

  1. http://addr:9999//abc

But the correct URL should be

  1. http://addr:9999/abc

The redundant / generated when call -stringByAppendingString: method.

huangapple
  • 本文由 发表于 2014年5月5日 09:38:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/23463601.html
匿名

发表评论

匿名网友

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

确定