iPhone 使用 NSURLConnection 发送 POST

Posted

技术标签:

【中文标题】iPhone 使用 NSURLConnection 发送 POST【英文标题】:iPhone sending POST with NSURLConnection 【发布时间】:2010-01-15 13:27:44 【问题描述】:

我在使用 NSURLConnection 将 POST 数据发送到 php 脚本时遇到了一些问题。这是我的代码:

    const char *bytes = [[NSString stringWithFormat:@"<?xml version=\"1.0\"?>\n<mydata>%@</mydata>", data] UTF8String];

    NSURL *url = [NSURL URLWithString:@"http://myurl.com/script.php"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[NSData dataWithBytes:bytes length:strlen(bytes)]];

    NSURLResponse *response;
    NSError *err;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
    NSLog(@"responseData: %@", responseData);

而我的 script.php 就是这么简单:

<?php
    echo $_POST['mydata'];
?>

这在过去对我有用,但由于某种原因,我现在从 NSLog(@"responseData: %@", responseData); 得到的输出只是“”而不是“theData”。

可能在某个地方出现了一些蹩脚的错误,但我似乎找不到?有什么想法吗?

【问题讨论】:

【参考方案1】:

您的数据有误。如果您希望在 PHP 的 $_POST 数组中找到数据,它应该如下所示:

const char *bytes = "mydata=Hello%20World";

如果要发送 XML 数据,则需要设置不同的 HTTP 内容类型。例如。你可以设置

application/xml; charset=utf-8

如果没有设置HTTP Content Type,则默认类型

application/x-www-form-urlencoded

将被使用。这种类型期望 POST 数据具有与 GET 请求中相同的格式。

但是,如果您设置不同的 HTTP 内容类型,例如 application/xml,则此数据不会添加到 PHP 中的 $_POST 数组中。您必须从输入流中读取原始数据。

试试这个:

NSString * str = [NSString stringWithFormat:@"<?xml version=\"1.0\"?>\n<mydata>%@</mydata>", data];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:[str dataUsingEncoding:NSUTF8StringEncoding]];

并在服务器上尝试以下 PHP:

$handle = fopen("php://input", "rb");
$http_raw_post_data = '';
while (!feof($handle)) 
    $http_raw_post_data .= fread($handle, 8192);

fclose($handle);

请注意,这仅在您的 POST 的 HTTP 标头不是 application/x-www-form-urlencoded 时才有效。如果是 application/x-www-form-urlencoded 那么 PHP 自己会读取所有的 post 数据,解码它(将其拆分为键/值对),最后将其添加到 $_POST 数组中。

【讨论】:

啊是的...干杯。但是responseData输出就像“”,你不打印NSData用%@吗? 感谢 [request setValue:@"xxx" forHTTPHeaderField:@"Content-Type"]; 嗨,我使用 HTTP Content-Type 的 "text/xml; charset=utf-8",发送请求没问题,但我使用 "application/xml; charset=utf-8" 也可以HTTP Content-Type 一起出现问题,数据返回:“服务器无法为请求提供服务,因为媒体类型不受支持”。那么发生了什么?【参考方案2】:

啊,是的……干杯。但是responseData输出就像“”,你不打印NSData用%@吗? – per_pilot 2010 年 1 月 15 日 13:57

那是因为你正在显示“字节”值,你应该将它传递给 NSString 以查看真正的消息

NSString *string = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
NSLog(@"responseData: %@", string);

【讨论】:

【参考方案3】:
NSString *post =[NSString stringWithFormat:@"usertype(%@),loginname(%@),password(%@)",txtuser.text,txtusername.text,txtpassword.text];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:@"http://www.dacinci.com/app/tes2/login_verify.php"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

NSError *error;
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *str=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];

【讨论】:

标准格式:...stringWithFormat:@"usertype=%@&loginname=%@&password=%@" ;)【参考方案4】:

POST 数据和 XML 数据不一样。您可以像以前一样发送 XML 数据,但 PHP 代码必须从请求正文中解析 XML。 PHP 的 xml_parse (http://php.net/manual/en/function.xml-parse.php) 可以帮助您做到这一点。

或者,如果您希望发送 POST 数据,请将请求正文设置为:

const char *bytes = [[NSString stringWithFormat:@"mydata=%@", data] UTF8String];

【讨论】:

【参考方案5】:

如果你使用 NSURLSession 那么在 ios9 中设置

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request addValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
request.HTTPMethod = @"POST";

在 PHP 集中

//connection to the database
$dbhandle = mysql_connect($hostname, $username, $password) 
  or die("Unable to connect to MySQL");
  echo "Connected to SQL.";

//select a database to work with
$selected = mysql_select_db($db,$dbhandle) 
  or die("Could not select anons db");
  echo "Connected to DB sucess.";

mysql_query("SET NAMES 'utf8'"); 
mysql_query("SET CHARACTER SET 'utf8'");
mysql_query("SET SESSION collation_connection = 'utf8_general_ci'");

在 db (MySql5) 中设置 utf-8_generic。

【讨论】:

以上是关于iPhone 使用 NSURLConnection 发送 POST的主要内容,如果未能解决你的问题,请参考以下文章

iphone OCMockObject 和单元测试从 NSURLConnection 继承的类

iPhone NSURLConnection:connectionDidFinishLoading - 如何将字符串返回给调用方法

我们如何在 iPhone Xcode 中处理多个 NSURLConnection?

iPhone NSURLConnection:如何处理返回的 NSData 对象?谷歌文档 API

与 NSURLConnection 委托方法相关的查询

NSURLSession/NSURLConnection HTTP 加载失败(kCFStreamErrorDomainSSL,-9813)错误不是在所有 iPhone 上?