从iOS发送多部分POST并读取PHP $ _POST中的参数?

我试图从iPhone / iPad发送一个多行文章到一个PHP服务,问题是,由于某种原因,POST内容types似乎是应用程序/ x-www-form-urlenconded,(我发现这个使用Wireshark)

这实际上是Wireshark POST数据包捕获的一个片段:

**Content-Type: application/x-www-form-urlencoded\r\n** Content-Length: 324\r\n [Content length: 324] Connection: keep-alive\r\n \r\n [Full request URI: http://my.server.com/mobile/tools/authentication] Line-based text data: application/x-www-form-urlencoded --0xKhTmLbOuNdArY\r\n Content-Disposition: form-data; name="login"\r\n \r\n hello@hello.com\r\n --0xKhTmLbOuNdArY\r\n Content-Disposition: form-data; name="password"\r\n \r\n somepassword\r\n --0xKhTmLbOuNdArY\r\n \r\n --0xKhTmLbOuNdArY--\r\n 

问题是,在服务器我试图从这个POST请求读取login和密码variables,但这是不可能的,因为我认为php认为POST请求是x-www-form-urlencoded ,所以如果我设置authentication.php来做:

 <?php echo("<pre>") print_r($_POST) echo("</pre>") ?> 

我得到这个:

 <pre>Array\n (\n [--0xKhTmLbOuNdArY\r\n Content-Disposition:_form-data;_name] => "login"\r\n \r\n hello@hello.com\r\n --0xKhTmLbOuNdArY\r\n Content-Disposition: form-data; name="password"\r\n \r\n somepassword\r\n --0xKhTmLbOuNdArY\r\n \r\n --0xKhTmLbOuNdArY--\r\n \n )\n </pre> 

这显然不好,因为如果我使用这个简单的html表单发送一个请求:

 <FORM action="http://my.server.com/mobile/tools/authentication.php" method="post"> <P> <LABEL for="login">E-mail: </LABEL> <INPUT type="text" name="login"><BR> <LABEL for="password">pass: </LABEL> <INPUT type="text" name="password"><BR> <INPUT type="submit" value="Send"> <INPUT type="reset"> </P> </FORM> 

我从表单中得到这个Wireshark跟踪:

  Content-Type: application/x-www-form-urlencoded\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n Accept-Encoding: gzip,deflate,sdch\r\n Accept-Language: en-US,en;q=0.8\r\n Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n Cookie: PHPSESSID=tpp10pbrdkkf5dg9qprlamfuu2\r\n \r\n [Full request URI: http://mymed2.sophia.inria.fr/mobile/tools/authentication.php] Line-based text data: application/x-www-form-urlencoded login=hello%40hello.com&password=somepassword 

而这个文本从authentication.phpprint_r($_POST)输出

 <pre>Array\n (\n [login] => hello@hello.com\n [password] => somepassword\n )\n </pre> 

这是我在Objective-C和Cocoa中构buildPOST请求的方式

 - (NSMutableURLRequest *) POSTRequestWithURL:(NSURL *)url andDataDictionary:(NSDictionary *) dictionary { // Create a POST request NSMutableURLRequest *myMedRequest = [NSMutableURLRequest requestWithURL:url]; [myMedRequest setHTTPMethod:@"POST"]; // Add HTTP header info // Note: POST boundaries are described here: http://www.vivtek.com/rfc1867.html // and here http://www.w3.org/TR/html4/interact/forms.html NSString *POSTBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"]; [myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@\r\n", POSTBoundary] forHTTPHeaderField:@"Content-Type"]; // Add HTTP Body NSMutableData *POSTBody = [NSMutableData data]; [POSTBody appendData:[[NSString stringWithFormat:@"--%@\r\n",POSTBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; // Add Key/Values to the Body NSEnumerator *enumerator = [dictionary keyEnumerator]; NSString *key; while ((key = [enumerator nextObject])) { [POSTBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]]; [POSTBody appendData:[[NSString stringWithFormat:@"%@", [dictionary objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]]; [POSTBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", POSTBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; } // Add the closing -- to the POST Form [POSTBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", POSTBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; // Add the body to the myMedRequest & return [myMedRequest setHTTPBody:POSTBody]; return myMedRequest; } 

如你所见,一开始我就这样做:

  [myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@\r\n", POSTBoundary] forHTTPHeaderField:@"Content-Type"]; 

但是在之前的Wireshark跟踪日志中,POST数据包被视为Content-Type:application / x-www-form-urlencoded,也许我在做别的事情呢?

谢谢 :)

编辑:我想避免像ASIHTTPRequest这样的外部框架,顺便说一句,ASIHTTPRequest的开发已被主要开发人员放弃,如此处所述

好吧,因为我找不到没有外部库的解决scheme,所以我修复了我的代码并将其开源 ,以防万一有人想使用它。

我发布的代码的问题是\ r \ n在线上

 [myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@\r\n", POSTBoundary] forHTTPHeaderField:@"Content-Type"]; 

去除那固定的一切。

希望这可以帮助别人:)