在说请求数据之前,我们先了解下URL
URL(Uniform Resource Locator)
统一资源定位符
格式为:
protocol(协议) hostname(主机名) port(端口号) path(路径)parameters(参数)
其中hostname
也可以换成主机ip
地址, 相当于域名,给ip
地址带个面具(mask
),方便大家记忆
通过URL
我们可以找到服务器上的资源位置,然后客户端就可以利用这个URL
发送请求(request)
,与服务器建立连接(connection)
,服务器对客户端的请求作出响应(response)
后,就会向客户端发送数据(data)
.
1.创建url
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
2.创建请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
3,创建连接并且发送请求
——(1)发送同步请求(如果请求的数据比较多,会花费时间阻塞主线程。优点:可以一次性得到所有请求的数据)
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
—-(2)发送异步请求(不会阻塞主线程,分多次获得数据)
第一种方式:BLOCK
块
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
NSLog(@"HttpError: %@%ld",connectionError.localizedDescription,(long)connectionError.code);
}else{
NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
NSString * responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"HttpResponseCode:%ld",(long)responseCode);
NSLog(@"HttpResponseBody %@",responseString);
}
}];
第二种方式:NSURLConnectionDelegate,NSURLConnectionDataDelegate
代理方法
[NSURLConnection connectionWithRequest:request delegate:self];
#pragma mark -- NSURLConnectionDelegate
//当客户端向服务器发请求的时候连接失败时调用的方法 返回连接失败的错误信息
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"请求失败了");
}
#pragma mark -- NSURLConnectionDataDelegate
//连接成功时服务器向客户端返回的响应信息
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
NSLog(@"HttpResponseCode:%ld",(long)responseCode);
mutableData = [[NSMutableData alloc]init];
}
//服务器向客户端返回数据响应的方法 会多次调用
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 使用追加数据的方法 把请求的数据追加到上一次数据的末尾
[mutableData appendData:data];
}
//服务器向客户端返回数据完成的时候响应的方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *dataStr = [[NSString alloc]initWithData:mutableData encoding:NSUTF8StringEncoding];
NSLog(@"======%@",dataStr);
}
上面介绍的是不带参数的URL
,那么带参数的URL
是怎么样的呢?
其实很简单,就是在path
后面加一个问号(?)
表示接下来的是参数parameter=%@
,多个参数之间用&
连接.
下面以图形的形式说明C/S
之间数据的关系:
了解了C/S
之间数据的关系,我们来了解下最常用的http
协议
http
协议采用了请求响应模型,也就是C/S
模型. 客户端向服务器发送一个请求报文,请求报文包含请求的方法,URL
,协议版本,请求头部和请求数据.服务器以一个状态行作为响应,响应的内容包括协议的版本,原因短语,状态码,响应头部和响应数据.
http报文分为请求报文和响应报文
请求报文 由四部分组成
<request-line> //请求行
<headers> //请求头部
<blank line> //空行
[<request-body>] //请求数据

请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。
HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
响应报文 也由四部分组成
<status-line> //状态行
<headers> //响应头部
<blank line>
[<response-body>] //响应数据
在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息
状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version
表示服务器HTTP
协议的版本;Status-Code
表示服务器发回的响应状态代码;Reason-Phrase
表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
• • 1xx:指示信息--表示请求已接收,继续处理。
• • 2xx:成功--表示请求已被成功接收、理解、接受。
• • 3xx:重定向--要完成请求必须进行更进一步的操作。
• • 4xx:客户端错误--请求有语法错误或请求无法实现。
• • 5xx:服务器端错误--服务器未能实现合法的请求。
常见状态代码、状态描述的说明如下。
• • 200 OK:客户端请求成功。
• • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
• • 401 Unauthorized:请求未经授权,这个状态代码必须。
• • 403 Forbidden:服务器收到请求,但是拒绝提供服务。
• • 404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
• • 500 Internal Server Error:服务器发生不可预期的错误。
• • 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
了解了以上的所有知识后我们来详细解析请求报文中的Get 和Post 方法
在api
文档中
httpUrl 就表示接口地址
httpArg表示请求参数(urlParam),比如[NSString stringWithFormat:@"name=%@&pwd=%@&command=2",_name,_pwd];
Get 方法:最常见的一种请求方式.请求参数和对应的值附加在URL
后面,利用一个问号(?)
代表URL
的结尾和请求参数的开始,各个数据之间用&
符号隔开
NSString * urlStr = [[NSString alloc] initWithFormat:@"%@?%@",httpUrl,httpArg];
NSURL * url = [NSURL URLWithString:urlStr];
NSURLRequest * request = [NSURLRequest requestWithURL:url];//如果想设置请求头的特殊属性就用NSMutableURLRequest创建
Post 方法:请求参数封装在http
请求数据内容中,以名称/值的形式出现,不会显示在URL
中
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:httpUrl];
我们通过[request setHTTPMethod:@"POST"];来设置为post方法,httpMethod默认为get方法
NSData * data = [httpArg dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];//将请求数据封装到<request-body>中
总结 HTTP
请求GET
和POST
的区别:
1.提交方面: get
请求的数据附在URL
之后,也就是HTTP
的协议头<request-line>
, post
请求的数据放在HTTP
的包体中<request-body>
2.传输数据大小方面:get
传输数据会受到URL
长度的限制,取决于操作系统以及服务器的支持.post
理论上不受限制,但实际各个web
服务器会规定对post
提交数据的大小进行限制
3.安全性方面: 通过get
提交的数据,会出现在URL
上,比如用户名和密码,由于登陆页面可能有浏览器缓存,其他人查看浏览器的历史记录,就可以发现你的账号和密码,而post
没必要担心.所以post
的安全性要比get
高.
请求报头:
请求报头允许客户端向服务端传递请求的附加信息以及客户端自身的信息
get
和post
方法都可以使用
[request addValue:@"9f57132e09df1ae87f52275d2fa8ecc9" forHTTPHeaderField:@"apikey"];
来设置请求报头(也就是参数位置在header
处).第一个参数表示参数值,第二个参数表示参数名.一般情况下api
文档会给我们提供以上参数的详细信息,如

但是http
也有常见的请求报头属性,详细请点这里https://en.wikipedia.org/wiki/List_of_HTTP_header_fields