使用具有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的其他(包括定制)方案稍有不同。 显然HTTPBody
和HTTPBodyStream
调用相关的NSURLRequest
对于前一个返回总是nil
。 这已经是[NSURLProtocol canInitWithRequest]
之前的调用决定了,因此自定义的NSURLProtocol
实现没有任何影响(它为时已晚)。
似乎不同的NSURLRequest
类用于http:
和https:
比'默认的'。 此类的默认GnuStep实现从HTTPBody
和HTTPBodyStream
调用始终返回nil
。 因此,特定的实现(例如PhoneGap中的一个,可能是Foundation Framework的一部分)会根据NSURLProtocol
咨询来选择NSURLRequest
类的类。 对于自定义方案,您将得到NSURLRequest
,该方法对于HTTPBody
和HTTPBodyStream
均返回nil
,这有效地禁止在自定义URI方案处理程序中使用POST方法(以及其他方法与body)。
也许有一种方法可以影响实际使用哪个NSURLRequest
类的决定,但目前我不知道它。
作为一种解决方法,您仍然可以使用http:
或https:
scheme并根据其他条件(例如主机名)决定[NSURLProtocol canInitWithRequest]
。
上一篇: Using a custom NSURLProtocol with UIWebView and POST requests