Я пытаюсь отправить многострочный пост из iPhone / iPad в службу php, проблема в том, что по какой-то причине POST Content-Type выглядит как application / x-www-form-urlenconded (я нашел это использование Wireshark)
На самом деле это фрагмент пакета POST-пакетов Wireshark:
**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, но это невозможно, так как я думаю, что 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
И этот текст выводится из print_r($_POST)
в authentication.php
<pre>Array\n (\n [login] => hello@hello.com\n [password] => somepassword\n )\n </pre>
Именно так я создаю запрос POST в Objective-C и Cocoa
- (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, может быть, я делаю что-то еще неправильно?
Благодаря 🙂
EDIT: Я хочу избежать внешних фреймворков, таких как ASIHTTPRequest, кстати, разработка ASIHTTPRequest была оставлена ведущим разработчиком, как указано здесь
Хорошо, поскольку я не мог найти решение без внешних библиотек, я исправил свой код и открыл его, если кто-то захочет его использовать.
Проблема с кодом, который я опубликовал, была \ r \ n на линии
[myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@\r\n", POSTBoundary] forHTTPHeaderField:@"Content-Type"];
Удаление этого исправлено.
Надеюсь, это поможет кому-то другому 🙂