从0.96版本开始,ASIHTTPRequest可以使用磁盘上的数据来作为请求体。这意味着不需要将文件完全读入内存中,这就避免的当使用大文件时的严重内存消耗。
使用这个特性的方法有好几种:
1
2
3
4
5
|
NSURL *url = [ NSURL URLWithString : @ "http://www.dreamingwish.com/" ];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL :url];
[request setPostValue : @ "foo" forKey : @ "post_var" ];
[request setFile : @ "/Users/ben/Desktop/bigfile.txt" forKey : @ "file" ];
[request startSynchronous ];
|
当使用setFile:forKey:时,ASIFormDataRequests 自动使用这个特性。request将会创建一个包含整个post体的临时文件。文件会一点一点写入post体。这样的request是由 CFReadStreamCreateForStreamedHTTPRequest创建的,它使用文件读取流来作为资源。
如果你明白自己的request体会很大,那么为这个request设置流式读取模式。
1 | [request setShouldStreamPostDataFromDisk : YES ]; |
下面的例子中,我们将一个NSData对象添加到post体。这有两个方法:从内存中添加(appendPostData:),或者从文件中添加(appendPostDataFromFile:);
1
2
3
4
5
6
|
NSURL *url = [ NSURL URLWithString : @ "http://www.dreamingwish.com/" ];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL :url];
[request setShouldStreamPostDataFromDisk : YES ];
[request appendPostData :myBigNSData];
[request appendPostDataFromFile : @ "/Users/ben/Desktop/bigfile.txt" ];
[request startSynchronous ];
|
这个例子中,我们想直接PUT一个大文件。我们得自己设置setPostBodyFilePath ,ASIHTTPRequest将使用这个文件来作为post体。
1
2
3
4
5
6
|
NSURL *url = [ NSURL URLWithString : @ "http://www.dreamingwish.com" ];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL :url];
[request setRequestMethod : @ "PUT" ];
[request setPostBodyFilePath : @ "/Users/ben/Desktop/another-big-one.txt" ];
[request setShouldStreamPostDataFromDisk : YES ];
[request startSynchronous ];
IMPORTANT:切勿对使用上述函数的request使用setPostBody——他们是互斥的。只有在你要自己建立request的请求体,并且还准备在内存中保持这个请求体时,才应该使用setPostBody。
使用gzip来处理压缩的响应数据从0.9版本开始,ASIHTTPRequest会提示服务器它可以接收gzip压缩过的数据。 许多web服务器可以在数据被发送之前压缩这些数据——这可以加快下载速度减少流量使用,但会让服务器的cpu(压缩数据)和客户端(解压数据)付 出代价。总的来说,只有特定的几种数据会被压缩——许多二进制格式的文件像jpeg,gif,png,swf和pdf已经压缩过他们的数据了,所以向客户 端发送这些数据时不会进行gzip压缩。文本文件例如网页和xml文件会被压缩,因为它们通常有大量的数据冗余。
怎样设置apache的mod_deflate来使用gzip压缩数据apache 2.x以上版本已经配备了mod_deflate扩展,这使得apache可以透明地压缩特定种类的数据。要开启这个特性,你需要在apache的配置文 件中启用mod_deflate。并将mod_deflate命令添加到你的虚拟主机配置或者.htaccess文件中。
在ASIHTTPRequest中使用gzip
当allowCompressedResponse 设置为YES时,ASIHTTPRequest将向request中增加一个Accept-Encoding头,表示我们可以接收gzip压缩过的数据。 如果响应头中包含一个Content-Encoding头指明数据是压缩过的,那么调用responseData 或者responseString 将会得到解压缩后的数据。你也可以通过调用rawResponseData来获得原始未压缩的数据。
相应数据的实时解压缩默认情况下,ASIHTTPRequest会等到request完成时才解压缩返回的数据。若设置request的shouldWaitToInflateCompressedResponses 属性为NO,ASIHTTPRequest将会对收到的数据进行实时解压缩。 在某些情况下,这会稍稍提升速度,因为数据可以在reqeust等待网络数据时进行处理。 如果你需要对响应数据流进行流处理(例如XML和JSON解析),这个特性会很有用。如果启用了这个选项,你可以通过实现代理函数request:didReceiveData:来将返回的网络数据一点一点喂给解析器。 注意,如果shouldWaitToInflateCompressedResponses 被设置为NO,那么原始(未解压)的数据会被抛弃。具体情况请查阅ASIHTTPRequest.h的代码注释。
使用gzip压缩request数据1.0.3版本的新特性就是gzip压缩request数据。使用这个特性,你可以通过设置shouldCompressRequestBody 为YES来使你的程序压缩POST/PUT的内容,默认值为NO。 apache的mod_deflate可以自动解压缩gzip压缩的请求体(通过合适的设置)。这个方法适用于CGI内容,但不适用于内容过滤器式的模块(例如mod PHP),这种情况下,你就必须自己解压缩数据。
ASIHTTPRequest-身份验证你可以查阅ASIHTTPRequest授权流程图来了解ASIHTTPRequest如何找到授权凭据,并将授权凭据应用到request上。 为URL指定要使用的用户名和密码
为request指定要使用的用户名和密码
将凭据存储到keychain如果打开了keychainPersistence,所有提供的可用的用户名和密码将被存储到keychain中,以后的request将会重用这些用户名密码,即使你关闭程序后重新打开也不影响。
如果你使用keychain但是想要自己管理它,你可以在ASIHTTPRequest.h文件里找到相关的类方法。 将凭据存储到session中如果打开了useSessionPersistence(默认即是如此),ASIHTTPRequest会把凭据存储到内存中,后来的request将会重用这些凭据。
NTLM授权要使用NTLM授权的Windows服务器,你还需要指定你要进行授权域。
使用代理来提供凭据你不一定非要提前指定授权凭据,你还可以让每个request在无法从session或keychain中找到凭据时向它们的代理请求凭据。如果你要连接到一个你并不清楚授权类型的服务器时,这是很有用的。 你的delegate必须实现authenticationNeededForRequest:方法,当request等待凭据 时,ASIHTTPRequest将会暂停这个request。如果你持有你需要的凭据,那么先为request设定凭据,然后调用[request retryUsingSuppliedCredentials]即可。如果你想取消授权,调用[request cancelAuthentication],此时,这个request也会被取消。 从1.0.8版开始,一次只能有一个request的delegate收到authenticationNeededForRequest: 或者 proxyAuthenticationNeededForRequest:。当delegate处理第一个request时,其他需要授权的 request将会被暂停。如果提供了一个凭据,当前进程中所有其他的request将会假定这个凭据对这个URL有效,并尝试重用这个凭据。如果 delegate取消了授权,并且队列的shouldCancelAllRequestsOnFailure值为YES,所有其他的request都将被 取消(它们也不会尝试请求凭据)。
使用内建的授权对话框(目前只对iOS有效)
这个特性归功于1.0.8版本的新类ASIAuthenticationDialog 。这个特性主要是用于授权代理(后面会介绍到),但是它也可以用来向用户取得授权凭据。 为了更好的用户体验,大多数(连接单一服务的)app必须为request的delegate实现authenticationNeededForRequest:方法,或者避免同时使用代理式授权。
但是,会有一些情况下,为普通的授权使用ASIHTTPRequest的标准授权对话框更好:
对于这些情况,为request设置shouldPresentAuthenticationDialog为YES,此时,如果你的代理没有实现 authenticationNeededForRequest:方法,那么用户将会看到这个对话框。 一次同时只有一个对话框可以显示出来,所以当一个对话框显示时,所有其他需要授权的request将会暂停。如果提供了一个凭据,当前进程中所有其 他的request将会假定这个凭据对这个URL有效,并尝试重用这个凭据。如果delegate取消了授权,并且队列的 shouldCancelAllRequestsOnFailure值为YES,所有其他的request都将被取消(它们也不会尝试请求凭据)。 对于同步请求的request,授权对话框不会显示出来。 这个对话框部分模仿了iPhone上Safari使用的授权对话框,它包含以下内容:
如果你想改变它的外观,你必须继承ASIHTTPRequest,并重写showAuthenticationDialog来显示你自己的对话框或ASIAuthenticationDialog子类。 在服务器请求凭据前向服务器发送凭据
在第一次生成request时,ASIHTTPRequest可以先向服务器发送凭据(如果有的话),而不是等服务器要求提供凭据时才提供凭据。这个特性可以提高使用授权的程序的执行效率,因为这个特性避免了多余的request。 对于基本授权模式,要触发这个行为,你必须手动设置request的authenticationScheme为kCFHTTPAuthenticationSchemeBasic:
对于其他授权方案,凭据也可以在服务器要求之前被发送,但是仅当有另一个request成功授权之后才行。 在以下情况下,你也许想要禁用这个特性:
要禁用这个特性,这样做:
|