В разделе 10.3.2 RFC 2616 есть примечание об этом поведении:
Примечание. При автоматическом перенаправлении запроса POST после
получение кода состояния 301, некоторые существующие пользовательские агенты HTTP / 1.0
по ошибке изменит его на запрос GET.
Так что это поведение кажется нестандартным, но историческим. Этот запрос GET
не является POST
, и в нем будет отсутствовать полезная нагрузка.
Интересно, что это тоже в том же разделе:
Если код состояния 301 получен в ответ на запрос другого
чем GET или HEAD, пользовательский агент НЕ ДОЛЖЕН автоматически перенаправлять
запрос, если он не может быть подтвержден пользователем, так как это может
изменить условия, на которых был выдан запрос.
Это довольно ясно и, кажется, указывает на то, что мы не можем это исправить, но я думаю, что игнорирование этого для целей наших собственных клиентов веб-сервисов для сервисов, которые мы выбираем (или контролируем), вероятно, является наименее плохой альтернативой.
Так, как мы решаем это?
Вместо willSendResponse:
в исходном вопросе я использую это:
- (NSURLRequest *)connection: (NSURLConnection *)connection
willSendRequest: (NSURLRequest *)request
redirectResponse: (NSURLResponse *)redirectResponse;
{
if (redirectResponse) {
// we don't use the new request built for us, except for the URL
NSURL *newURL = [request URL];
// Previously, store the original request in _originalRequest.
// We rely on that here!
NSMutableURLRequest *newRequest = [_originalRequest mutableCopy];
[newRequest setURL: newURL];
return newRequest;
} else {
return request;
}
}
Идея заключается в том, что вместо клонирования нового запроса и попытки сформировать его так же, как отправляет мне Cocoa Touch, я создаю клон исходного запроса и изменяю только URL-адрес в соответствии с запросом, отправленным мне Cocoa Touch. , Этот исходный запрос по-прежнему POST
с прикрепленной полезной нагрузкой.
Если вы управляете сервером, стоит прочитать RFC 2616, раздел 10.3 , чтобы увидеть, есть ли лучший код, который вы можете использовать (при проверке, конечно, iOS обрабатывает лучший код как это должно).
Вы также можете сделать изменяемую копию перенаправленного запроса и заменить его метод HTTP на метод HTTP исходного запроса. Тот же самый общий принцип, хотя это будет способствовать сохранению вещей из нового запроса, а не из старого. В некоторых случаях это может работать лучше, но я еще не проверял это.