AFNetworking 发布请求未到达 Sinatra 应用程序

发布于 2025-01-07 04:17:18 字数 2455 浏览 2 评论 0原文

我正在尝试使用我制作的 Sinatra API 从我的 iPhone 发布请求。目前我的 Sinatra 应用程序正在做的就是打印出已发送给它的请求。这是代码:

post '/profile' do

    puts "#{params}"
end

我的 Objective-c 也非常简单。它所做的只是向我的 API 发送一个 post 请求:

NSURL *url = [NSURL URLWithString:kBaseURLString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:JSON, @"json", nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"/profile" parameters:dictionary];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"SUCCESS");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"%@", error);
}];
[operation start];

当 JSON(在 obj-c 的第 3 行)是一个非常短的字符串,例如 @"test" 时,Sinatra 会像这样正确地打印出来:

{"json"=>"test"}

当我使用实际的JSON 配置文件数据,这是一个非常长的 JSON blob,Sinatra 将其打印如下:

{"json"=>"(null)"}

我无法弄清楚为什么长 blob 会通过。我 100% 确定我传递了正确的字符串,但 Sinatra 没有收到它。我目前的理论是 Sinatra 对请求有最大字符数限制,但我对 Sinatra 和 Ruby 很陌生,我不知道如何测试它。出了什么问题?

更新:

首先,感谢 Kjuly 的建议。我发现我对 Sinatra 的字符限制的看法是错误的。在 obj-c 中,我正在记录第 3 行包含 JSON blob 的字典,并且它包含 json blob。但是,当我在第 4 行记录 NSMutableURLRequest 的正文时,正文为空。当我使用我的小 JSON blob 时,主体已被填充。

NSMutableURLRequest 有字符限制吗?谁能想到为什么它不接受带有大 JSON blob 的非常大的字典,但不接受带有小 JSON blob 的原因。

谢谢!

再次更新

请求正文现在可以正确填写。我必须将此行添加到第 3 行中:

[httpClient setParameterEncoding:AFJSONParameterEncoding];

现在我在来自 Sinatra 的 HTTPResponse 中收到此响应:

Error Domain=com.alamofire.networking.error Code=-1016 "Expected content type {(
    "text/json",
    "application/json",
    "text/javascript"
)}, got text/html"

Sinatra 现在只是打印

{}

而不是 {"json"=>"(null)"}

仍然不确定发生了什么。

更新 3

好吧,我以为是来自 Sinatra 的 HTTPResponse - text/json 内容 - 是因为我从 Sinatra 返回了一个 text/html 回到 AFNetworking。我现在已经检查了 Sinatra 接收到的正文,我的巨大 JSON 斑点就在那里。然而,“params”仍然是空的。

有人知道为什么吗?

已修复

看起来当您将 JSON 发布到 sinatra 时,您必须直接读取请求正文。在 Sinatra 中,您可以这样做:

profile = JSON.parse(request.body.read.to_s)

那么 profile 就是您解析的对象。

I'm trying to post a request from my iPhone with a Sinatra API I made. Currently all my Sinatra app is doing is printing out the request that has been sent to it. This is the code for that:

post '/profile' do

    puts "#{params}"
end

My objective-c is pretty simple as well. All it does is send a post request to my API:

NSURL *url = [NSURL URLWithString:kBaseURLString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:JSON, @"json", nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"/profile" parameters:dictionary];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"SUCCESS");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"%@", error);
}];
[operation start];

When JSON (in line 3 of the obj-c) is a very short string, such as @"test", Sinatra prints it out correctly like this:

{"json"=>"test"}

When I use the actual JSON profile data, which is a very long JSON blob, Sinatra prints it out as this:

{"json"=>"(null)"}

I can't figure out why the long blob is getting through. I am 100% sure that i'm passing the correct string, but Sinatra is not receiving it. My current theory is that Sinatra has a max character limit on requests, but I am new to Sinatra and Ruby, and I have no idea how I'd test that. What is going wrong?

UPDATE:

First off, thanks Kjuly for your suggestions. I figured out that I was wrong on the character limit on Sinatra thing. In obj-c I'm doing a log of the dictionary that has the JSON blob on line 3, and it has the json blob. However, when I log the body of the NSMutableURLRequest on line 4, the body is empty. When I use my tiny JSON blob, the body is filled.

Does NSMutableURLRequest have a character limit? Can anyone think of a reason why it would not accept my very large dictionary with the large JSON blob, but not with the small one.

Thanks!

UPDATE AGAIN:

The request body now fills correctly. I had to add this line into line 3:

[httpClient setParameterEncoding:AFJSONParameterEncoding];

Now I am getting this response back in the HTTPResponse from Sinatra:

Error Domain=com.alamofire.networking.error Code=-1016 "Expected content type {(
    "text/json",
    "application/json",
    "text/javascript"
)}, got text/html"

Sinatra is now just printing

{}

Instead of {"json"=>"(null)"}

Still not sure what's going on.

Update 3

Okay, what I thought was the HTTPResponse from Sinatra - the text/json stuff - was because I was returning a text/html from Sinatra back in AFNetworking. I have now checked the body that Sinatra is receiving, and my giant JSON blob is in there. However, "params" is still empty.

Anyone have any idea why?

FIXED IT

Looks like when you post JSON to sinatra you have to read the body of the request directly. In Sinatra, you do this like so:

profile = JSON.parse(request.body.read.to_s)

Then profile is your parsed object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

毅然前行 2025-01-14 04:17:18

我认为您需要使用 AFJSONRequestOperation 来代替,这里有一个示例代码:

// Fetch Data from server
NSURL *url = [NSURL URLWithString:@"https://gowalla.com/users/mattt.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFJSONRequestOperation * operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
                                                success:^(NSURLRequest * request, NSHTTPURLResponse * response, id JSON) {
                                                  NSLog(@"Name: %@ %@", [JSON valueForKeyPath:@"first_name"], [JSON valueForKeyPath:@"last_name"]);
                                                }
                                                failure:nil];
[operation start];

或者您可以访问 WIKI 页面,请参阅第 4 步:下载并解析 JSON

I think you need to use AFJSONRequestOperation instead, here's a sample code:

// Fetch Data from server
NSURL *url = [NSURL URLWithString:@"https://gowalla.com/users/mattt.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFJSONRequestOperation * operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
                                                success:^(NSURLRequest * request, NSHTTPURLResponse * response, id JSON) {
                                                  NSLog(@"Name: %@ %@", [JSON valueForKeyPath:@"first_name"], [JSON valueForKeyPath:@"last_name"]);
                                                }
                                                failure:nil];
[operation start];

Or you can visit the WIKI PAGE, see Step 4: Download and Parse JSON.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文