原文地址 http://bbs.neworigin.net/forum.php?mod=viewthread&tid=488

在开发网络相关的应用,比如微博应用时,就必然需要使用到HTTP请求来发送或者接收数据。最主要的就是使用GET方法或者POST方法。本文将详细介绍HTTP请求在iOS开发中的编程实现。
1、对于HTTP请求的基本介绍
这里不对原理做过多的介绍,大家可以Google之。对于完全不了解的童鞋,这里作个基本的说明。举新浪开放平台为例,我们要从手机发布一条新的状态,需 要通过网络向新浪微博的服务器发送请求,这个请求中包含了我们要发送的状态信息。请求的URL必须是新浪开放平台指定的才行。比如这个发送状态,URL是https://api.weibo.com/2/statuses/update.json。 大家可以自己到开放平台查看,然后使用的HTTP请求方式是POST。然后要附带一些请求参数。HTTP请求有GET,POST,DELETE等等方式, 不同的方式它的URL request格式不同,对于大多数使用情况,使用GET和POST就行。然后如果发送请求成功的话,就可以从服务器接受到相关的信息。
GET是比较简单的请求方式,在URL中直接就包含了要发送的所有参数。还是以新浪开放平台的请求为例。我们要获取获取某个用户最新发表的微博列表。那么这个基本的URL是https://api.weibo.com/2/statuses/user_timeline.json ,然后由于这个请求主要是接收数据,要附带的请求参数最基本的就两个,一个是access_token,一个uid就是用户的编号。
那么一个基本的GET请求的URL就是
https://api.weibo.com/2/statuses ... uid=xxxxxxxxxxxxxxx
那么在iOS开发中,确定了URL,然后就是建立URLRequest,NSURLConnection去实现请求。当然,在实际中,GET方法也有它相关的报文格式,如下:

  1. GET /api.weibo.com/2/statuses/user_timeline.json?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxx&uid=xxxxxxxxxxxxxxx HTTP/1.1
  2. Host: api.weibo.com
  3. HTTP/1.1 200 OK
  4. Content-Type: text/xml; charset=utf-8Content-Length: length

复制代码

这里的很多参数都是默认,在Xcode中创建NSURLConnection的时候会自动加上。
下面说一下POST。POST可以这样理解主要用于向服务器上传数据,简单一点的是上传文字,复杂一点的是上传图片声音等等。那么对于这种需求显然如果使 用GET的话,那么这URL未免会太长。因此有POST方式的存在,可以在基本的URL的情况下,再附加一个数据包,包含要上传的数据,然后和URL一起 发送给服务器。
POST方法有两种格式,一种是基本的格式,一般用于发送文字信息。
Post请求基本格式如下:

  1. POST /login.asp HTTP/1.1
  2. Host: www.example.com
  3. Content-Type: application/x-www-form-urlencoded
  4. Content-Length: 35
  5. username=wantsoft&password=password   //post的数据

复制代码

另一种是multipart/form-data,格式如下

  1. POST /upload_file/UploadFile HTTP/1.1
  2. Accept: text/plain, */*
  3. Accept-Language: zh-cn
  4. Host: www.example.com
  5. Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6
  6. User-Agent: Mozilla/4.0 (compatible; OpenOffice.org)
  7. Content-Length: 424
  8. Connection: Keep-Alive -----------------------------7d33a816d302b6
  9. Content-Disposition:form-data;
  10. name="userfile";
  11. filename="userfile"
  12. Content-Type: application/octet-stream abbXXXccc
  13. -----------------------------7d33a816d302b6
  14. Content-Disposition: form-data;
  15. name="text1" foo
  16. -----------------------------7d33a816d302b6
  17. Content-Disposition: form-data;
  18. name="password1" bar
  19. -----------------------------7d33a816d302b6--

复制代码

看起来比较复杂,其实就是把请求数据通过分界线也就是Boundary分开,至于开头的一些内容,很多都是默认,无需考虑。
2、Xcode编程实现
2.1 HTTP请求的基本方法
STEP 1: 创建URL
一般我们用于URL的字符串。通过字符串创建URL

  1. NSString URLString;
  2. NSURL *URL = [NSURLURLWithString:[URLStringstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

复制代码

上面附加的stringByAddingPercentEscapesUsingEncoding:是为了保证URL字符串有效。
STEP 2:创建URLRequest

  1. NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:finalURLcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:SR_TIME_OUT_INTERVAL];
  2. //如果是GET
  3. [URLRequest setHTTPMethod:@"GET"];
  4. //如果是POST
  5. [URLRequest setHTTPBody:[HTTPBodyStringdataUsingEncoding:NSUTF8StringEncoding]];
  6. [URLRequestsetHTTPMethod:@"POST"];

复制代码

STEP 3:通过NSURLConnection实现请求
一般有两种方式,如果不需要知道请求的进度,比如文字上传,那么用简单的异步请求。如下:

  1. NSOperationQueue *queue = [[NSOperationQueuealloc]init];
  2. [NSURLConnectionsendAsynchronousRequest:self.URLRequestqueue:queuecompletionHandler:^(NSURLResponse *response,NSData *data,NSError *error){...};

复制代码

如果要知道请求的进度,比如图片发送的情况。那么就应该创建一个NSURLConnection的实例,并设置其delegate,通过其delegate方法来获取请求的实时状态,具体使用方法详见开发文档。
2.2 HTTP GET方法的实现
主要讲如何创建NSURLRequest
这里我直接将我写的方法放下面:

  1. - (NSURLRequest *)HTTPGETRequestForURL:(NSURL *)url parameters:(NSDictionary *)parameters
  2. {
  3. NSString *URLFellowString = [@"?"stringByAppendingString:[selfHTTPBodyWithParameters:parameters]];
  4. NSString *finalURLString = [[url.absoluteStringstringByAppendingString:URLFellowString]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  5. NSURL *finalURL = [NSURLURLWithString:finalURLString];
  6. NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:finalURLcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:TIME_OUT_INTERVAL];
  7. [URLRequestsetHTTPMethod:@"GET"];
  8. return URLRequest;
  9. }
  10. - (NSString *)HTTPBodyWithParameters:(NSDictionary *)parameters
  11. {
  12. NSMutableArray *parametersArray = [[NSMutableArrayalloc]init];
  13. for (NSString *keyin [parametersallKeys]) {
  14. id value = [parameters objectForKey:key];
  15. if ([value isKindOfClass:[NSStringclass]]) {
  16. [parametersArrayaddObject:[NSStringstringWithFormat:@"%@=%@",key,value]];
  17. }
  18. }
  19. return [parametersArray componentsJoinedByString:@"&"];
  20. }

复制代码

基本上就是通过方法把请求参数与URL连接起来,然后创建NSURLRequest
2.3 HTTP POST 基本方法的实现

  1. - (NSURLRequest *)HTTPPOSTNormalRequestForURL:(NSURL *)url parameters:(NSDictionary *)parameters
  2. {
  3. NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:urlcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:TIME_OUT_INTERVAL];
  4. NSString *HTTPBodyString = [selfHTTPBodyWithParameters:parameters];
  5. [URLRequest setHTTPBody:[HTTPBodyStringdataUsingEncoding:NSUTF8StringEncoding]];
  6. [URLRequestsetHTTPMethod:@"POST"];
  7. return URLRequest;
  8. }

复制代码

这个和GET极其类似,只不过是把请求参数放在了HTTPBody中了。
2.4 HTTP POST Multipart

  1. - (NSURLRequest *)HTTPPOSTMultipartRequestForURL:(NSURL *)url parameters:(NSDictionary *)parameters
  2. {
  3. NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:urlcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:TIME_OUT_INTERVAL];
  4. NSString *contentType = [NSStringstringWithFormat:@"multipart/form-data;boundary=%@",SR_POST_BOUNDARY];
  5. // 设置内容的类型 contentType,这完全是按照POST的格式来设置
  6. [URLRequestsetValue:contentType forHTTPHeaderField:@"Content-Type"];
  7. [URLRequestsetHTTPMethod:@"POST"];
  8. [URLRequest setHTTPBody:[selfHTTPPOSTMultipartBodyWithParameters:parameters]];
  9. return URLRequest;
  10. }
  11. // 用于创建Multipart Body,需要分割线,也是完全参考POST格式
  12. - (NSData *)HTTPPOSTMultipartBodyWithParameters:(NSDictionary *)parameters
  13. {
  14. NSMutableData *body = [NSMutableDatadata];
  15. // Add Body Prefix String
  16. [body appendData:[[NSStringstringWithFormat:@"--%@\r\n",SR_POST_BOUNDARY]dataUsingEncoding:NSUTF8StringEncoding]];
  17. // Add Main Body
  18. for (NSString *keyin [parametersallKeys]) {
  19. id value = [parameters objectForKey:key];
  20. if ([value isKindOfClass:[NSStringclass]]){
  21. [body appendData:[[NSStringstringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",key,value]dataUsingEncoding:NSUTF8StringEncoding]];
  22. [body appendData:[[NSStringstringWithFormat:@"--%@\r\n",SR_POST_BOUNDARY]dataUsingEncoding:NSUTF8StringEncoding]];
  23. }else {
  24. NSLog(@"please use addMultiPartData:withName:type:filename: Methods to implement");
  25. }
  26. }
  27. return body;
  28. }
  29. // 在最后要附加上请求参数中的图片等等大的数据!
  30. - (void)addMultiPartData:(NSData *)data
  31. withName:(NSString *)name
  32. type:(NSString *)type
  33. filename:(NSString *)filename
  34. {
  35. NSMutableURLRequest *URLRequest = [self.URLRequestmutableCopy];
  36. NSMutableData *body = [URLRequest.HTTPBodymutableCopy];
  37. // Step 1
  38. NSString *disposition = [[NSStringalloc]init];
  39. if (!filename) {
  40. disposition =
  41. [NSStringstringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name, filename];
  42. }else {
  43. disposition =
  44. [NSStringstringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name, name];
  45. }
  46. [body appendData:[dispositiondataUsingEncoding:NSUTF8StringEncoding]];
  47. // Step 2
  48. NSString *contentType = [NSStringstringWithFormat:@"Content-Type: %@\r\n\r\n",type];
  49. [body appendData:[contentTypedataUsingEncoding:NSUTF8StringEncoding]];
  50. // Step 3
  51. [bodyappendData:data];
  52. // Step 4 Add suffix boundary
  53. NSString *boundary = [NSStringstringWithFormat:@"\r\n--%@--\r\n",SR_POST_BOUNDARY];
  54. [body appendData:[boundarydataUsingEncoding:NSUTF8StringEncoding]];
  55. // Step 5
  56. [URLRequestsetHTTPBody:body];
  57. self.URLRequest = URLRequest;
  58. }

复制代码

3、下面说一下接受数据
一般我们要把NSData数据变成JSON数据,大都是情况下获得的JSON Object是NSDictionary或NSArray
基本方法是

  1. id receivedData = [NSJSONSerializationJSONObjectWithData:dataoptions:NSJSONReadingMutableContainers |NSJSONReadingMutableLeaveserror:nil];

复制代码

然后就可以进行相关的处理了!

HTTP请求 GET POST 网络编程实现的更多相关文章

  1. HTTP请求 GET POST 网络编程实现(转)

    尊重原作者收集的资料,复制粘贴只为了避免作者文章出处哪天抽风了访问不了了导致资料消失. 原文地址 http://bbs.neworigin.net/forum.php?mod=viewthread&a ...

  2. 8.6 day27 网络编程 osi七层协议 Time模块补充知识 TCP协议

    Time模块补充知识 date和datetime区别是什么? date 就是年月日 datetime就是年月时时分秒 以下代码为什么会报错? import json from datetime imp ...

  3. Java网络编程 -- BIO 阻塞式网络编程

    阻塞IO的含义 阻塞(blocking)IO :阻塞是指结果返回之前,线程会被挂起,函数只有在得到结果之后(或超时)才会返回 非阻塞(non-blocking)IO :非阻塞和阻塞的概念相对应,指在不 ...

  4. Java工程师学习指南第5部分:Java网络编程与NIO

    本文整理了微信公众号[Java技术江湖]发表和转载过的Java网络编程相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧. 深度解读 Tomcat 中的 NIO 模型 [Java基本功]浅 ...

  5. JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)

    本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...

  6. 网络编程---(数据请求+slider)将网络上的大文件下载到本地,并打印其进度

    网络编程---将网络上的大文件下载到本地,并打印其进度. 点击"開始传输"button.将网络上的大文件先下载下来,下载完毕后,保存到本地. UI效果图例如以下: watermar ...

  7. 【网络编程3】网络编程基础-arp请求(局域网主机扫描)

    ARP协议 ARP(Add ress Resolution Protocol)地址解析协议位于数据链路层,是根据IP地址获取MAC地址的一个协议. ARP 查看指令 arp -a 显示所有接口的当前A ...

  8. Java网络编程和NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型

    Java网络编程与NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型 知识点 nio 下 I/O 阻塞与非阻塞实现 SocketChannel 介绍 I/O 多路复用的原理 事件选择器与 ...

  9. Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型

    本文转载自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 http ...

随机推荐

  1. 解决iis+php+mysql访问速度慢的方法

    IIS7.5网站访问PHP响应慢的原因原因是PHP5.3以上支持IPv6协议,但是大家的服务器未使用IPv6,当访问PHP的时候会连接MySQL的地址为localhost,系统会会先用IPv6连接,但 ...

  2. js回顾1

    1.正则:/^[0-9a-zZ-Z_]*&/ //匹配0到多个,+是1到多个,?0或多个,.任意值/^[0-9a-zZ-Z_]{6,}&/ //精确到至少6位\w查找单词字符检测:te ...

  3. 关于css样式1

    背景色 可以使用 background-color 属性为元素设置背景色.这个属性接受任何合法的颜色值. 这条规则把元素的背景设置为灰色: p {background-color: gray;} 如果 ...

  4. Sql 常用时间转换

    CONVERT(varchar(100), GETDATE(), 0); -- 08 31 2015 04:57PM CONVERT(varchar(100), GETDATE(), 20); --2 ...

  5. JavaScript数据类型

    当说到JavaScript的数据类型时,好多做了很多年web的朋友甚至还不太清楚.这应该算是最基础的js知识了.我觉得有必要在这记录一下,方便自己和大家查看. 最基本的,js有五种数据类型:undef ...

  6. js⑧

    window对象表示浏览器中打开的窗口, 它是JavaScript浏览器对象模型中的顶层对象.其中还包括了 - Document: 使我们可以从脚本中对 HTML 页面中的所有元素进行访问. - Hi ...

  7. VM虚拟主机怎么设置网络

    VMware是很受欢迎的虚拟机,在我们平时的工作中需要经常用到,此文简单总结了平时使用的三种网络配置方式,具体的原理没有去深究.我估计咱也研究不懂! 虚拟主机安装很简单,网上教程有很多,但是有很多新手 ...

  8. PHP 单引号 与双引号区别

    在PHP中,字符串的定义可以使用单引号,也可以使用双引号. PHP允许我们在双引号串中直接包含字串变量,双引号串中的变量将被解释而且替换,而单引号串中的内容总被认为是普通字符.例如: $foo = 2 ...

  9. Spark源码学习1.3——TaskSetManager.scala

    TaskSetManager.scala TaskSet是指一系列被提交的task,一般是代表特定的stage中丢失的partition.TaskSetManager通过一个TaskScheduler ...

  10. nodejs常用模块之url

    统一资源定位符(url)充当http服务器用来处理来自客户端的请求的一个地址标签.它为把一个请求发到正确的服务器的特定端口上,并访问合适的数据提供了所有需要的信息.