HTTP通信过程 - 请求
HTTP
协议规定
:1
个完整的由
客户端
发给
服务器
的
HTTP
请求中包含以下内容
请求行
:包含了
请求方法
、
请求资源路径
、
HTTP
协议版本
GET /MJServer/resources/images/1.jpg HTTP/1.1
请求头
:包含了
对客户端的环境描述
、
客户端请求的主机地址
等信息
Host: 192.168.1.105:8080 // 客户端想访问的服务器主机地址
User-Agent: Mozilla/5.0(Macintosh; Intel Mac OS X 10.9) Firefox/30.0
// 客户端的类型,客户端的软件环境
Accept: text/html,*/* // 客户端所能接收的数据类型
Accept-Language: zh-cn // 客户端的语言环境
Accept-Encoding: gzip // 客户端支持的数据压缩格式
请求体
:
客户端
发给
服务器
的具体数据,比如文件数据
HTTP通信过程- 响应
HTTP
协议规定
:1
个完整的
HTTP
响应
中包含以下内容
状态行
:包含了
HTTP
协议版本
、
状态码
、
状态英文名称
HTTP/1.1 200 OK
响应头
:包含了
对服务器的描述
、
对返回数据的描述
Server:Apache-Coyote/1.1 // 服务器的类型
Content-Type: image/jpeg // 返回数据的类型
Content-Length: 56811 // 返回数据的长度
Date: Mon, 23 Jun2014 12:54:52 GMT // 响应的时间
实体内容
:
服务器
返回给
客户端
的具体数据,比如文件数据
HTTP通信过程
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GET和POST的主要区别表现在数据传递上
GET
在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开,比如
http://ww.test.com/login?username=123&pwd=234&type=JSON(注:不能出现空格)
由于浏览器和服务器对URL长度有限制,因此在URL后面附带的参数是有限制的,通常不能超过1KB
POST
发给服务器的参数全部放在请求体中
理论上,POST传递的数据量没有限制(具体还得看服务器的处理能力)
GET和POST的选择
选择
GET和
POST的建议
如果要传递大量数据,比如文件上传,只能用
POST请求
GET的安全性比
POST要差些,如果包含机密\敏感信息,建议用
POST
如果仅仅是索取数据(数据查询),建议使用
GET
如果是增加、修改、删除数据,建议使用
POST
POST登陆:
/**POST*/
- (void)postLogin
{
// 1. url
NSString *urlString = @"http://127.0.0.1/login.php";
NSURL *url = [NSURL URLWithString:urlString];
// 2. 可变的请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];
// 2.1 指定http的访问方法,服务器短才知道如何访问
request.HTTPMethod = @"POST";
// 2.2 指定数据体,数据体的内容可以从firebug里面直接拷贝
// username=zhangsan&password=zhang
NSString *username = @"张三";
NSString *pwd = @"zhang";
NSString *bobyStr = [NSString stringWithFormat:@"username=%@&password=%@", username, pwd];
// 2.2.1 跟服务器的交互,全部传递的二进制
request.HTTPBody = [bobyStr dataUsingEncoding:NSUTF8StringEncoding];
// 3. 连接
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 反序列化
id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSLog(@"%@", result);
}];
}
- (void)getLogin
{
/**
GET
http://127.0.0.1/login.php?username=%@&password=%@
1. http://127.0.0.1主机地址
2. login.php是服务器负责登录的脚本(php,java)
3. ? 后面的就是参数,是给服务器传递的参数
参数的格式
变量名=值
username=@"zhangsan"
4. & 如果是多个参数,通过这个进行连接。
*/
// 1. url
NSString *username = @"张三";
NSString *pwd = @"zhang";
NSString *urlString = [NSString stringWithFormat:@"http://192.168.10.9/login.php?username=%@&password=%@",username, pwd];
// url里面不能包含中文空格特殊符号
// 如果有,需要百分号转义
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
// 2. 请求
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];
// 3. 连接
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 反序列化
id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSLog(@"%@", result);
}];
}
POST上传:
#import "ViewController.h"
#import "NSMutableURLRequest+Multipart.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self postUpLoad];
}
- (void)postUpLoad {
// 1. url
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/post/upload.php"];
// 2. post请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url andLoaclFilePath:[[NSBundle mainBundle] pathForResource:@"001.png" ofType:nil] andFileName:@"123456.png"];
// 3. 连接
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 反序列化处理
id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSLog(@"result = %@", result);
}];
}
#import <UIKit/UIKit.h>
@interface NSMutableURLRequest (Multipart)
/**
url: 要上传的服务器的地址
loaclFilePath: 要上传的文件的全路径
fileName:保存到服务器的文件名
*/
+ (instancetype)requestWithURL:(NSURL *)url andLoaclFilePath:(NSString *)loaclFilePath andFileName:(NSString *)fileName;
@end
#import "NSMutableURLRequest+Multipart.h"
/**随便的字符串作为分隔符*/
static NSString *boundary = @"itcastupload";
@implementation NSMutableURLRequest (Multipart)
+ (instancetype)requestWithURL:(NSURL *)url andLoaclFilePath:(NSString *)loaclFilePath andFileName:(NSString *)fileName
{
// 2. post请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];
// 2.1 指定post方法
request.HTTPMethod = @"POST";
// 2.2 拼接数据体
NSMutableData *dataM = [NSMutableData data];
// 1. \r\n--(可以随便写, 但是不能有中文)\r\n
NSString *str = [NSString stringWithFormat:@"\r\n--%@\r\n", boundary];
[dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
// 2. Content-Disposition: form-data; name="userfile(php脚本中用来读取文件的字段)"; filename="demo.json(要保存到服务器的文件名)"
str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\" \r\n", fileName];
[dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
// 3. Content-Type: application/octet-stream(上传文件的类型)\r\n\r\n
str = @"Content-Type: application/octet-stream\r\n\r\n";
[dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
// 4. 要上传的文件的二进制流
// 要上传图片的二进制
[dataM appendData:[NSData dataWithContentsOfFile:loaclFilePath]];
// 5. \r\n--(可以随便写, 但是不能有中文)--\r\n
str = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary];
[dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
// 2.4 设置请求体
request.HTTPBody = dataM;
// 设置请求头
// Content-Length(文件的大小) 290
// Content-Type multipart/form-data; boundary(分隔符)=(可以随便写, 但是不能有中文)
NSString *headerStr = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:headerStr forHTTPHeaderField:@"Content-Type"];
return request;
}
@end
POST上传JSON:
- (void)viewDidLoad {
[super viewDidLoad];
// 1. url
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/post/postjson.php"];
// 2. POST请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];
// 2.1 设置hTTP方法
request.HTTPMethod = @"POST";
// 2.2 上传json类型数据 (本质就是一个字符串,特殊的字符串)
// 序列化,将NSArray/NSDictionary转成 特殊数据类型 的二进制数据
// 反序列化, 将服务器返回的二进制转成NSArray/NSDictionary
NSDictionary *dict1 = @{@"name" : @"xiaofang", @"age" : @"18"};
NSDictionary *dict2 = @{@"name" : @"xiaosan", @"age" : @(108)};
NSArray *arrray = @[dict1, dict2];
/**
- Top level object is an NSArray or NSDictionary
顶级节点是字典或者数组
- All objects are NSString, NSNumber, NSArray, NSDictionary, or NSNull
所有的对象是 NSString, NSNumber, NSArray, NSDictionary, or NSNull
- All dictionary keys are NSStrings
所有字典的key 是 NSString
- NSNumbers are not NaN or infinity
NSNumbers必须指定,不能是无穷大
+ (BOOL)isValidJSONObject:(id)obj;
用来检验给定的对象是否能够被序列化
*/
// 检验给定的对象是否能够被序列化
if (![NSJSONSerialization isValidJSONObject:arrray]) {
NSLog(@"格式不正确,不能被序列化");
return;
}
request.HTTPBody = [NSJSONSerialization dataWithJSONObject:arrray options:0 error:NULL];
// 3. 连接
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 返回的二进制数据
id result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"result = %@", result);
}];
}