1,GET/POST请求区别。
GET:get请求的参数拼接在url地址后面,而url地址的长度是有限制的,所以get请求请求的数据长度有限,一般用户数据量比较小的请求:(页面跳转等操作等)。虽然登录操作的数据量也非常小,但是因为get参数的url地址栏中,登录密码等信息会直接暴露出来,所以登录操作的密码即使加密,也会使用post请求来完成。
POST:弥补了get请求的明文,数据量小的缺陷。
2,同步/异步请求的区别
同步:同步请求会直接在主线程中进行操作。主线程一般做界面刷新等操作,然而同步请求会导致界面卡死,用户体验很差,所以在请求数据时,一般使用异步请求。用到同步请求时 ,一般是在开始界面,如果在app的首页要有数据请求,可以使用同步请求,让界面卡死在开始界面,当数据请求完成后,再进入到首页,防止数据还未请求完成就跳转到首页,用户体验不好。
异步请求:异步请求会单开一个线程,所以不会阻塞主线程,界面不会卡死。
3,四种网络请求方式:(GET同步,GET异步,POST同步,POST异步)
1)GET同步请求
/**
* 发起GET同步请求
*
* @param method 网络请求地址
* @param parameters 参数
* @param callback 回调方法
*/
- (void)sendGetSynchronizeRequestWithMethod:(NSString *)method parameters:(NSDictionary *)parameters callback:(Callback)callback {
// 发起请求
NSError *error = nil;
// 配置get请求参数(configGetUrlRequestWithMethod方法将在后面介绍) 、接收请求返回数据
NSData *data = [NSURLConnection sendSynchronousRequest:[self configGetUrlRequestWithMethod:method parameters:parameters] returningResponse:nil error:&error];
if (error) {
// 如果出错,就输出错误,并回调
NSLog(@"request did failed with error message '%@'", [error localizedDescription]);
callback(error, nil);
} else {
// JSON解析,回调
NSMutableDictionary *object = [selfJSONObjectWithData:data];
callback(nil, object);
}
}
2)GET异步请求
GET异步请求需要实现NSURLConnectionDataDelegate代理方法
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; // 接收到数据
- (void)connectionDidFinishLoading:(NSURLConnection *)connection; // 加载完成(数据全部接受完)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; // 网络请求
发起GET异步请求
/**
* 发起GET异步请求
*
* @param method 网络请求地址
* @param parameters 参数
* @param callback 回调方法
*/
- (void)sendGetAsynchronizeRequestWithMethod:(NSString *)method parameters:(NSDictionary *)parameters callback:(Callback)callback {
self.callback = callback;
// 配置get请求参数(configGetUrlRequestWithMethod方法将在后面介绍) 、接收请求返回数据
[NSURLConnection connectionWithRequest:[self configPostURLRequestWithMethod:method parameters:parameters] delegate:self];
}
代理方法实现
/**
* 接收到数据时的代理
*
* @param connection 网络连接
* @param data 接收到的数据
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if (!_responseData) {
_responseData = [[NSMutableData alloc] init];
}
// 在数据量较大时,会多次走这个方法,接收数据,需要将每次接收到的数据拼接起来
[_responseData appendData:data];
}
/**
* 请求完成代理
*
* @param connection 网络连接
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// 关闭网络连接
[connection cancel];
// JSON解析
id object = [self JSONObjectWithData:_responseData];
// 将接收数据的参数赋空,用于下次请求继续接收新的数据
_responseData.length = 0;
// 如果有回调方法,则走回调方法
if (_callback) {
_callback(nil, object);
}
// 释放回调方法
self.callback = nil;
}
/**
* 请求出错代理
*
* @param connection 网络连接
* @param error 错误
*/
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// 关闭网络连接
[connection cancel];
// 如果有回调方法,则走回调方法
if (_callback) {
_callback(error, nil);
}
// 释放回调方法
self.callback = nil;
}
3),GET请求参数配置:将GET请求的参数拼接在url之后
/**
* 配置GET请求
*
* @param method 网络请求地址
* @param parameters 参数
*
* @return配置完成的请求
*/
- (NSURLRequest *)configGetUrlRequestWithMethod:(NSString *)method parameters:(NSDictionary *)parameters {
// 因为GET的参数是拼接在URL地址后面的,所以将method参数copy为可变字符串
NSMutableString *httpBodyString = [method mutableCopy];
// GET请求的URL地址在参数前,需要加上?,表示参数列表开始
[httpBodyString appendString:@"?"];
// 循环将参数拼接到URL后面
for (NSString *key in parameters) {
[httpBodyString appendFormat:@"%@=%@&", key, [parameters objectForKey:key]];
}
// 将string转为URL
NSURL *url = [NSURL URLWithString:httpBodyString];
//通过url生成网络请求
return [NSURLRequest requestWithURL:url];
}
4),请求完成后,JSON数据解析
/**
* JSON解析返回数据
*
* @param data 返回的数据
*
* @return解析为JSON对象
*/
- (id)JSONObjectWithData:(NSData *)data {
// 如果没有数据返回,则直接不解析
if (data.length == 0) {
return nil;
}
// 初始化解析错误
NSError *error = nil;
// JSON解析
id object = [NSJSONSerializationJSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
return object;
}
5).POST同步请求
/**
* 发起POST同步请求
*
* @param method 网络请求地址
* @param parameters 参数
* @param callback 回调方法
*/
- (void)sendPostSynchronizeRequestWithMethod:(NSString *)method parameters:(NSDictionary *)parameters callback:(Callback)callback {
// 发起请求
NSError *error = nil;
// post参数配置(configPostURLRequestWithMethod会在后面介绍) 接收请求返回的数据
NSData *data = [NSURLConnection sendSynchronousRequest:[self configPostURLRequestWithMethod:method parameters:parameters] returningResponse:nil error:&error];
if (error) {
// 如果出错,就输出错误,并回调
NSLog(@"request did failed with error message '%@'", [error localizedDescription]);
callback(error, nil);
} else {
// JSON解析,回调
NSMutableDictionary *object = [selfJSONObjectWithData:data];
callback(nil, object);
}
}
6).POST异步请求
/**
* 发起POST异步请求
*
* @param method 网络请求地址
* @param parameters 参数
* @param callback 回调方法
*/
- (void)sendPostAsynchronizeRequestWithMethod:(NSString *)method parameters:(NSDictionary *)parameters callback:(Callback)callback {
self.callback = callback;
[NSURLConnection connectionWithRequest:[self configPostURLRequestWithMethod:method parameters:parameters] delegate:self];
}
7),POST请求参数配置
/**
* 配置POST请求
*
* @param method 网络请求地址
* @param parameters 参数
*
* @return配置完成的请求
*/
- (NSURLRequest *)configPostURLRequestWithMethod:(NSString *)method parameters:(NSDictionary *)parameters {
// POST请求的参数是放在httpbody中的,所以可以先将请求地址转为url
NSURL *url = [NSURLURLWithString:method];
// 需要不停地拼接参数,所以request需要是可变的
NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:url];
// 配置请求方法
request.HTTPMethod = @"POST";
// 请求超时时长
request.timeoutInterval = 10;
// 配置请求参数
NSMutableString *httpBodyString = [NSMutableStringstring];
for (NSString *key in parameters) {
[httpBodyString appendFormat:@"%@=%@&", key, [parameters objectForKey:key]];
}
// 将参数加在httpbody中
request.HTTPBody = [httpBodyString dataUsingEncoding:NSUTF8StringEncoding];
return request;
}