使用具有UIWebView和POST请求的自定义NSURLProtocol

在我的iOS应用中,我使用了一个UIWebView和一个自定义协议(使用我自己的NSURLProtocol实现)。 我一直很小心地确保每当我加载一个url时,我都会在我的UIWebView中加载这样的内容:

myprotocol:// MYSERVER / mypath中

并且在我的NSURLProtocol实现中,我使用NSURLRequest的可变副本,将URL转换为http:并将其发送到我的服务器。

一切适用于HTTP GET请求。 我遇到的问题是POST请求。 如果请求使用我的自定义协议,UIWebView似乎没有正确编码HTTPBody中的表单数据。

一个解决方法,因为我使用HTTPS服务器请求,是我注册我的协议处理程序拦截http:而不是myprotocol:并且我可以将所有调用转换为https:这个其他问题,在这里,指向我解:

但我想知道是否有其他方法和/或更好的方法来完成我想要的。


与其尝试使用POST请求,一个解决方法是继续对myprotocol:// URL使用GET请求,但将它们在您的NSURLProtocol实现中转换为http://和POST请求,并使用请求查询字符串作为POST的正文。

使用GET请求发送大量数据的担心是在请求链的某处,请求行可能会被截断。 但是,使用本地实施的协议,这似乎不成问题。

我写了一个简短的科尔多瓦测试应用程序来进行实验,并且我发现我能够通过一点点超过1 MiB的数据发送,而没有麻烦的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的情况下构建响应数据Transfer-Encoding:chunked (如http://http-echo.jgate.de/ )。


不幸的是,它看起来像http:https: scheme请求处理的方式与Foundation Framework的其他(包括定制)方案稍有不同。 显然HTTPBodyHTTPBodyStream调用相关的NSURLRequest对于前一个返回总是nil 。 这已经是[NSURLProtocol canInitWithRequest]之前的调用决定了,因此自定义的NSURLProtocol实现没有任何影响(它为时已晚)。

似乎不同的NSURLRequest类用于http:https:比'默认的'。 此类的默认GnuStep实现从HTTPBodyHTTPBodyStream调用始终返回nil 。 因此,特定的实现(例如PhoneGap中的一个,可能是Foundation Framework的一部分)会根据NSURLProtocol咨询来选择NSURLRequest类的类。 对于自定义方案,您将得到NSURLRequest ,该方法对于HTTPBodyHTTPBodyStream均返回nil ,这有效地禁止在自定义URI方案处理程序中使用POST方法(以及其他方法与body)。

也许有一种方法可以影响实际使用哪个NSURLRequest类的决定,但目前我不知道它。

作为一种解决方法,您仍然可以使用http:https: scheme并根据其他条件(例如主机名)决定[NSURLProtocol canInitWithRequest]

链接地址: http://www.djcxy.com/p/5927.html

上一篇: Using a custom NSURLProtocol with UIWebView and POST requests

下一篇: Custom NSURLProtocol not used in second webview