在我的iOS应用程序中,我使用的是UIWebView和自定义协议(使用我自己的NSURLProtocol实现)。我一直非常小心确保无论何时加载网址,我都会将这样的内容加载到我的UIWebView中:
myprotocol:// MYSERVER / mypath中
在我的NSURLProtocol实现中,我获取了NSURLRequest的可变副本,将URL转换为http:并将其发送到我的服务器。
一切都适用于HTTP GET请求。我遇到的问题是POST请求。如果请求使用我的自定义协议,似乎UIWebView没有正确编码HTTPBody中的表单数据。
因为我使用HTTPS来处理我的服务器请求,所以我注册了我的协议处理程序以拦截http:而不是myprotocol:我可以将所有调用转换为https:另一个问题,{{3 ,指出我的解决方案:
但我想知道是否有任何替代和/或更好的方式来实现我想要的东西。
答案 0 :(得分:6)
不是尝试使用POST请求,而是继续使用myprotocol://
网址的GET请求,但要将NSURLProtocol
实施中的转换为http://
, 使用请求查询字符串作为POST主体的POST请求。
使用GET请求发送大量数据的担忧是在请求链的某个地方,请求行可能会被截断。但是,这似乎不是一个问题,使用本地实现的协议。
我写了一个简短的Cordova测试应用程序进行实验,我发现我能够毫不费力地向HTTP请求回送服务发送超过1 MiB的数据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
的情况下构建响应数据(就像来自{的响应一样) {3}})。
答案 1 :(得分:4)
不幸的是,http:
和https:
方案请求的处理方式与Foundation Framework的其他(包括自定义)方案略有不同。显然HTTPBody
和HTTPBodyStream
对相关NSURLRequest
的调用始终为nil
。这是在事先调用[NSURLProtocol canInitWithRequest]
时决定的,因此自定义NSURLProtocol
实现无法影响(为时已晚)。
似乎NSURLRequest
和http:
使用的不同https:
类比'默认值'。此类的默认GnuStep实现从nil
和HTTPBody
调用返回始终 HTTPBodyStream
。因此,特定的实现(例如PhoneGap下的一个,可能是Foundation Framework的一部分)选择NSURLRequest
- 基于方案的类型,事先咨询NSURLProtocol
。对于自定义方案,NSURLRequest
为nil
和HTTPBody
返回HTTPBodyStream
,这有效地禁用了自定义URI方案处理程序中POST方法(以及其他方法与body)的使用
也许有一种方法可以影响我实际使用NSURLRequest
类的决定,但我目前还不知道。
作为一种变通方法,您仍然可以使用http:
或https:
计划,并根据其他条件(例如主机名)决定[NSURLProtocol canInitWithRequest]
。