如何使用 AFNetworking 发送 HTTP POST 请求?

How to send HTTP POST request with AFNetworking?

我这里有一个远程地址:http://damp-sands-2243.herokuapp.com/students

我需要通过 API 电话插入新学生。

这是我用 javasript 做的:

var data  = {"name":"Meg",
             "regi_number":38};

$(document).ready(function(){
$.ajax({
        type: "POST",
        url: "/students/",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: JSON.stringify(data),
        success: function(){console.log("boo");}
      });
});

您可以转到 URL 并使用浏览器的 javascript 控制台来检查它是否有效。

现在,我的问题是从 Objective C 做同样的事情。这是我所做的,

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"name": @"reza"};
[manager POST:@"http://damp-sands-2243.herokuapp.com/students"
   parameters:parameters
      success:^(AFHTTPRequestOperation *operation, id responseObject) {
   // NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

现在我收到以下错误:

2015-05-14 01:16:58.568 logintest[20916:722708] 
Error: Error Domain=com.alamofire.error.serialization.response Code=-1011 
"Request failed: client error (422)" UserInfo=0x7fed68e2d430 
{NSUnderlyingError=0x7fed68c46900 

"Request failed: unacceptable content-type: text/html", 
com.alamofire.serialization.response.error.response=<NSHTTPURLResponse:
 0x7fed68c2b8b0> { URL: http://damp-sands-2243.herokuapp.com/students } 
{ status code: 422, headers {
Connection = close;
"Content-Length" = 1547;
"Content-Type" = "text/html; charset=utf-8";
Date = "Wed, 13 May 2015 19:16:57 GMT";
Server = "WEBrick/1.3.1 (Ruby/2.0.0/2015-04-13)";
Via = "1.1 vegur";
"X-Request-Id" = "c6ea9bf8-05a6-4497-8585-47d21f59726f";
"X-Runtime" = "1.369345";
} }, NSErrorFailingURLKey=http://damp-sands-2243.herokuapp.com/students, 
    com.alamofire.serialization.response.error.data=
<3c21444f 43545950 45206874 6d6c3e0a 3c68746d 6c3e0a3c 68656164 3e0a2020 3c746974 6c653e54 68652063 68616e67 6520796f 75207761 6e746564 20776173 2072656a 65637465 64202834 3232293c 2f746974 6c653e0a 20203c6d 65746120 6e616d65 3d227669 6577706f 72742220 636f6e74 656e743d 22776964 74683d64 65766963 652d7769 6474682c 696e6974 69616c2d 7363616c 653d3122 3e0a2020 3c737479 6c653e0a 2020626f 6479207b 0a202020 20626163 6b67726f 756e642d 636f6c6f 723a2023 45464546 45463b0a 20202020 636f6c6f 723a2023 32453246 33303b0a 20202020 74657874 2d616c69 676e3a20 63656e74 65723b0a 20202020 666f6e74 2d66616d 696c793a 20617269 616c2c20 73616e73 2d736572 69663b0a 20202020 6d617267 696e3a20 303b0a20 207d0a0a 20206469 762e6469 616c6f67 207b0a20 20202077 69647468 3a203935 253b0a20 2020206d 61782d77 69647468 3a203333 656d3b0a 20202020 6d617267 696e3a20 34656d20 6175746f 20303b0a 20207d0a 0a202064 69762e64 69616c6f 67203e20 64697620 7b0a2020 2020626f 72646572 3a203170 7820736f 6c696420 23434343 3b0a2020 2020626f 72646572 2d726967 68742d63 6f6c6f72 3a202339 39393b0a 20202020 626f7264 65722d6c 6566742d 636f6c6f 723a2023 3939393b 0a202020 20626f72 6465722d 626f7474 6f6d2d63 6f6c6f72 3a202342 42423b0a 20202020 626f7264 65722d74 6f703a20 23423030 31303020 736f6c69 64203470 783b0a20 20202062 6f726465 722d746f 702d6c65 66742d72 61646975 733a2039 70783b0a 20202020 626f7264 65722d74 6f702d72 69676874 2d726164 6975733a 20397078 3b0a2020 20206261 636b6772 6f756e64 2d636f6c 6f723a20 77686974 653b0a20 20202070 61646469 6e673a20 37707820 31322520 303b0a20 20202062 6f782d73 6861646f 773a2030 20337078 20387078 20726762 61283530 2c203530 2c203530 2c20302e 3137293b 0a20207d 0a0a2020 6831207b 0a202020 20666f6e 742d7369 7a653a20 31303025 3b0a2020 2020636f 6c6f723a 20233733 30453135 3b0a2020 20206c69 6e652d68 65696768 743a2031 2e35656d 3b0a2020 7d0a0a20 20646976 2e646961 6c6f6720 3e207020 7b0a2020 20206d61 7267696e 3a203020 30203165 6d3b0a20 20202070 61646469 6e673a20 31656d3b 0a202020 20626163 6b67726f 756e642d 636f6c6f 723a2023 46374637 46373b0a 20202020 626f7264 65723a20 31707820 736f6c69 64202343 43433b0a 20202020 626f7264 65722d72 69676874 2d636f6c 6f723a20 23393939 3b0a2020 2020626f 72646572 2d6c6566 742d636f 6c6f723a 20233939 393b0a20 20202062 6f726465 722d626f 74746f6d 2d636f6c 6f723a20 23393939 3b0a2020 2020626f 72646572 2d626f74 746f6d2d 6c656674 2d726164 6975733a 20347078 3b0a2020 2020626f 72646572 2d626f74 746f6d2d 72696768 742d7261 64697573 3a203470 783b0a20 20202062 6f726465 722d746f 702d636f 6c6f723a 20234441 44414441 3b0a2020 2020636f 6c6f723a 20233636 363b0a20 20202062 6f782d73 6861646f 773a2030 20337078 20387078 20726762 61283530 2c203530 2c203530 2c20302e 3137293b 0a20207d 0a20203c 2f737479 6c653e0a 3c2f6865 61643e0a 0a3c626f 64793e0a 20203c21 2d2d2054 68697320 66696c65 206c6976 65732069 6e207075 626c6963 2f343232 2e68746d 6c202d2d 3e0a2020 3c646976 20636c61 73733d22 6469616c 6f67223e 0a202020 203c6469 763e0a20 20202020 203c6831 3e546865 20636861 6e676520 796f7520 77616e74 65642077 61732072 656a6563 7465642e 3c2f6831 3e0a2020 20202020 3c703e4d 61796265 20796f75 20747269 65642074 6f206368 616e6765 20736f6d 65746869 6e672079 6f752064 69646e27 74206861 76652061 63636573 7320746f 2e3c2f70 3e0a2020 20203c2f 6469763e 0a202020 203c703e 49662079 6f752061 72652074 68652061 70706c69 63617469 6f6e206f 776e6572 20636865 636b2074 6865206c 6f677320 666f7220 6d6f7265 20696e66 6f726d61 74696f6e 2e3c2f70 3e0a2020 3c2f6469 763e0a3c 2f626f64 793e0a3c 2f68746d 6c3e0a>,
 NSLocalizedDescription=Request failed: client error (422)}

这是与 csrf 令牌相关的问题吗? 如何从我的 objective C 代码发送 POST 请求?

You can see my code here

我可以使用下面的 CURL 命令

 curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST https://damp-sands-2243.herokuapp.com/students -d "{\"student\":{\"name\":\"Choity\",\"regi_number\":\"10000\"}}"

错误很明显。内容类型设置为 text/html,而它应该是 application/json,就像在 javascript 中一样。在发出请求之前尝试设置请求序列化程序。

manager.requestSerializer = [AFJSONRequestSerializer serializer];

由于您正在尝试发送一些 JSON 数据,您的 manager 应该将请求的 header 的内容类型设置为 application/json。尝试在执行请求之前放入这行代码。

[manager setRequestSerializer:[AFJSONRequestSerializer serializer]];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

出现这个问题是因为我没有添加 HTTP Header 参数 "Accept"。因此缺少以下行。

[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];

另一方面,我更改了后端以防止它在通过此代码json请求时生成csrf令牌

skip_before_action :verify_authenticity_token,
                 :if => Proc.new { |c| c.request.format == 'application/json' }

forntent 代码现在看起来像这样:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 [manager setRequestSerializer:[AFJSONRequestSerializer serializer]];
 [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
 [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];

  NSDictionary *parameters = @{@"student":@{@"name":@"Reyan",@"regi_number":@"55"}};
 [manager POST:@"https://damp-sands-2243.herokuapp.com/students"

   parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
 }];

我也可以使用 CURL 命令进行测试:

 curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST https://damp-sands-2243.herokuapp.com/students -d "{\"student\":{\"name\":\"Choity\",\"regi_number\":\"10000\"}}"