iPhone - странное поведение, когда '&' включено в тело HTTP-запроса - PullRequest
0 голосов
/ 24 февраля 2012

У меня очень странная проблема, связанная с отправкой запроса POST из моего приложения для iPhone.

Приложению необходимо отправить данные HTTP-сообщения стороннему сервису. Запрос - это XML, и он получит ответ XML. Вот мой код для отправки запроса:

-(void)sendRequest:(NSString *)aRequest
{
    //aRequest parameter contains the XML string to send.
    //this string is already entity-encoded
    isDataRequest = NO;
    //the following line will created string REQUEST=<myxml>
    NSString *httpBody =  [NSString stringWithFormat:@"%@=%@",requestString,aRequest];
    //I'm not sure what this next string is doing, frankly, as I didn't write this code initially
    httpBody = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)httpBody, NULL, CFSTR("+"), kCFStringEncodingUTF8) autorelease];   
    NSData *aData = [httpBody dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kOOURLRequest]] autorelease]; 
    [request setHTTPBody:aData];
    [request setHTTPMethod:@"POST"];
    self.feedURLConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
}

Это прекрасно работает, если XML-запрос не содержит символа &, например, этот XML-запрос:

<?xml version="1.0"?>
<request type="search" group="0" language="en" version="2.5.2">
    <auth>
        <serial>623E1579-AC18-571B-9022-3659764542E7</serial>
    </auth>
    <data>
        <location>
            <lattitude>51.528536</lattitude>
            <longtitude>-0.108865</longtitude>
        </location>
        <search>archive</search>
    </data>
</request>

отправляется, как ожидается, и правильный ответ получен, как ожидается.

Однако, когда запрос содержит & символ (в частности, в элементе «search») - примерно так:

<?xml version="1.0"?>
<request type="search" group="0" language="en" version="2.5.2">
    <auth>
        <serial>623E1579-AC18-571B-9022-3659764542E7</serial>
    </auth>
    <data>
        <location>
            <lattitude>51.528536</lattitude>
            <longtitude>-0.108865</longtitude>
        </location>
        <search>&amp; archive</search>
    </data>
</request>

На сервер отправляется только все, вплоть до символа &. Сервер, кажется, не получает ничего, кроме этого персонажа. Обратите внимание, что у меня есть примерно такой же код, работающий в приложении для Android, и все работает правильно, поэтому на сервере это не проблема.

Буду очень признателен за любые идеи, как мне исправить это!

1 Ответ

0 голосов
/ 24 февраля 2012

Благодаря комментарию Зафа я наконец-то его разобрал.Я использовал WireShark, чтобы увидеть, что на самом деле было отправлено на сервер, и обнаружил, что запрос не был закодирован полностью.В окончательном теле HTTP присутствовал реальный символ & (часть &amp;).Естественно, это не очень хорошо работало на стороне сервера, потому что он получал что-то вроде:

REQUEST=first_half_of_request&amp;second_half_of_request

Когда сервер декодировал переменные POST, & был взят как разделитель переменных, поэтомуДля переменной REQUEST было установлено только значение first_half_of_request - все до & char.

Решение было довольно простым.В строке

httpBody = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)httpBody, NULL, CFSTR("+"), kCFStringEncodingUTF8) autorelease];

замените CFSTR("+") на CFSTR("+&"), чтобы также кодировать &.Теперь это в сочетании с кодировкой объектов (&amp; для &) привело к отправке на сервер правильных данных и получению правильного ответа.

...