Использование пользовательского NSURLProtocol с UIWEBVIEW и POST запросов

StackOverflow https://stackoverflow.com/questions/9301611

Вопрос

В моем приложении для iOS я использую UIWebView и пользовательский протокол (с моей собственной реализацией nsurlProtocol). Я был довольно осторожен с тем, чтобы убедиться, что всякий раз, когда загружаю URL, я загружаю что -то подобное в свой UIWebView:

myprotocol: // myserver/mypath

И в моей реализации nsurlprotocol я беру изменяющуюся копию NsurlRequest, преобразовываю URL в HTTP: и отправляю это на мой сервер.

Все работает для HTTP Get запросов. Проблема, с которой я сталкиваюсь, связана с запросами. Похоже, что UIWebView не должным образом кодирует данные формы в HTTPBody, если в запросе используется мой пользовательский протокол.

Одним из рабочих обходных данных, поскольку я использую HTTPS для запросов на сервер, является то, что я регистрирую свой обработчик протокола для перехвата http: вместо myprotocol: и я могу конвертировать все вызовы в HTTPS: этот другой вопрос, здесь, указал мне на это решение:

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

Это было полезно?

Решение

Вместо того, чтобы пытаться использовать запросы на почту, одна работа должна продолжать использовать запросы на получение запросов myprotocol:// URL -адреса, но трансформируйте их в своем NSURLProtocol реализация в http:// а также Разместите запрос на ваш сервер, используя строку запроса запроса в качестве корпуса сообщения.

Беспокойство с использованием запросов GET для отправки больших объемов данных заключается в том, что где -то вдоль цепочки запросов линия запроса может быть усечена. Однако это не является проблемой с локально внедренными протоколами.

Я написал короткое тестовое приложение Cordova для эксперимента, и я обнаружил, что смог отправить чуть более 1 MIB данных без проблем в сервис Echoing HTTP -запроса http://http-echo.jgate.de/

Вот мой startLoading реализация:

- (void)startLoading {
    NSURL *url = [[self request] URL];
    NSString *query = [url query];
    // Create a copy of `url` without the query string.
    url = [[[NSURL alloc] initWithScheme:@"http" host:@"http-echo.jgate.de" path:[url path]] autorelease];
    NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:url];
    [newRequest setHTTPMethod:@"POST"];
    [newRequest setAllHTTPHeaderFields:[[self request] allHTTPHeaderFields]];
    [newRequest addValue:@"close" forHTTPHeaderField:@"Connection"];
    [newRequest addValue:@"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    [newRequest setHTTPBody:[query dataUsingEncoding:NSUTF8StringEncoding]];
    urlConnection = [[NSURLConnection alloc] initWithRequest:newRequest delegate:self];
    if (urlConnection) {
        receivedData = [[NSMutableData data] retain];
    }
}

Затем я внедрил NSURLConnection Методы протокола для пересылки к соответствующему NSURLProtocolClient метод, но создание данных ответа в случае Transfer-Encoding:chunked (как в случае ответов http://http-echo.jgate.de/).

Другие советы

К сожалению, это похоже на это http: а также https: Запросы схемы обрабатываются чуть иначе, чем другие (включая пользовательские) схемы по основам. Очевидно HTTPBody а также HTTPBodyStream вызывает актуальность NSURLRequest возвращается всегда nil для бывших. Это решительно уже предшествует звонку [NSURLProtocol canInitWithRequest] поэтому обычай NSURLProtocol Реализация не может влиять на это (уже слишком поздно).

Кажется, что другой NSURLRequest Класс используется для http: а также https: чем «по умолчанию один». Реализация GNUSTEP этого класса по умолчанию всегда nil из HTTPBody а также HTTPBodyStream вызовы Поэтому конкретные реализации (например, один под PhoneGap, вероятно, часть Foundation Framework) выбирают NSURLRequest-Type of Class на основе схемы предшествующего консультации, который с NSURLProtocol. Анкет Для пользовательских схем вы получаете NSURLRequest это возвращается nil для обоих HTTPBody а также HTTPBodyStream который эффективно отключает использование метода Post (и других методов с телом) в пользовательском обработчике схемы URI.

Может быть, есть способ влиять на решение о котором NSURLRequest Класс фактически используется, но в настоящее время мне неизвестно.

В качестве обходного пути вы все равно можете использовать http: или же https: схема и решайте в [NSURLProtocol canInitWithRequest] на основе других критериев (например, имя хоста).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top