Отправка многочастного POST из iOS и чтение параметров в PHP $ _POST? - PullRequest
9 голосов
/ 12 октября 2011

Я пытаюсь отправить многострочное сообщение с iPhone / iPad в службу php, проблема в том, что по какой-то причине тип содержимого POST выглядит как application / 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, но это невозможно, так как я думаю, что php думает, что запрос POST x-www-form-urlencoded, поэтому, если я настрою authentication.php для:

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

Я получаю это:

<code><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

Это явно не хорошо, так как если я отправлю запрос, используя эту простую 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

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

Этокак я создаю запрос 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, может, я что-то не так делаю?

Спасибо:)

РЕДАКТИРОВАТЬ: я хочу избежать внешних каркасов, таких как ASIHTTPRequest, кстати, ведущий разработчик отказался от разработки ASIHTTPRequest, как указано здесь

1 Ответ

19 голосов
/ 23 октября 2011

Хорошо, поскольку я не мог найти решение без внешних библиотек, я исправил свой код и с открытым исходным кодом , на случай, если кто-то захочет его использовать.

Проблема с кодом, который я разместил, была \ r \ n в строке

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

Удаление, которое исправило все.

Надеюсь, это поможет кому-то еще:)

...