一、URL的编码
URL中一旦出现了特殊字符(比如中文、空格),需要进行编码。
比如:
编码前:https://www.baidu.com/s?wd=百度
编码后:https://www.baidu.com/s?wd=%E5%8D%8E%E4%B8%BA
- 0、URL的组成?参考iOS官方文档 Foundation篇---URLs
- 1、为什么要编码? 参考浅析URL编码
- 2、ios编码方法参考iOS的URL编码
- 3、post请求一般不需要,将一些特殊字符参数放在请求体内不会有什么解析歧义。自然发送get请求、webview加载一个请求时出现特殊字符时需要。
二、请求头和响应头
2.1、请求头字段
有关要获取的资源或客户端本身消息的消息头
一个ios程序代码示例:
NSString *urlString = @"http://testct.56cold.com/wechat/user/login”;
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @“POST”;
NSString *str = [NSString stringWithFormat:@"username=1e00000000&password=666e66”];
request.HTTPBody = [str dataUsingEncoding:NSUTF8StringEncoding];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
[task resume];
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error{
NSLog(@"请求完成或者是失败%@",error); NSLog(@"%@",task.currentRequest.allHTTPHeaderFields);
}
控制台打印:
青花瓷抓包截图:
字段名 | 说明 | 示例 |
---|---|---|
User-Agent | 客户端的身份标识 | 444/1/CFNetwork/1209Darwin/20.2.0 |
Host | 服务器的域名、端口号 | testct.56cold.com |
Accept-Charset | 能够接受的字符集 | GB2312,utf-8;q=0.7, *;q=0.7 |
Accept-Encoding | 能够接受的编码方式列表 | gzip, deflate |
Accept-Language | 能够接受的响应内容的自然语言列表 | en-us |
Content-Length | 求体的长度(字节为单位) | 36 |
Content-Type | 请求体的类型 | application/x-www-form-urlencoded |
Connection | 客户端想要优先使用的连接类型 | keep-alive |
Accept | 能够接受的响应内容类型 | text/plain |
Range | 仅请求某个实体的一部分。字节偏移以 开始 | bytes=500-599 |
Cookie | 之前由服务器通过Set-Cookies发送的cookies |
2.1.2、Accept
用来告知(服务器)客户端可以处理的内容类型,这种内容类型用MIME类型来表示。借助内容协商机制, 服务器可以从诸多备选项中选择一项进行应用,并使用 Content-Type
应答头通知客户端它的选择。浏览器会基于请求的上下文来为这个请求头设置合适的值
Accept: text/html
Accept: image/*
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, /;q=0.8
Accept:*/: 接受任何类型的数据
对于ios原生CFNetwork请求默认是Accept:*/,接受任何类型的数据。
2.1.3、Content-Type
告诉服务器所发送数据的类型,这样服务端就知道如何去处理收到的数据。比如application/json,代表发送端发送的数据格式是json.
- 1、application/x-www-form-urlencode
一般是默认的请求数据编码形式。用&分隔参数,用=分隔键和值,字符用URL编码方式进行编码。比如:username=18500000&password=66666
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type”];
回忆一下get请求数据的传递也是这种编码方式。
NSString *urlString = @"http://tstt.56cold.com/wechat/user/login?username=18500000000&password=666666”;
- 2、 application/json
请求数据编码形式是序列化的JSON字符串{"username":"18500000000","password":”666666”}
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type”];
注意:我们在编码时传递数据时,必须根据设置的Content-Type去处理请求体的数据,如果说你设置了application/json,你就不能随意的
NSString *str = [NSString stringWithFormat:@"username=18500000000&password=666666”]; request.HTTPBody = [str dataUsingEncoding:NSUTF8StringEncoding]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type”];
像这样硬生生的传递了application/x-www-form-urlencode的编码格式,这样服务器肯定会给你报参数错误
AFN设置请求体
:
NSString *URLString = @"http://testct.56locold.com/wechat/user/login”;
NSDictionary *parameters = @{@"username": @"18500000000", @"password": @"666666”};
1、URL Form Parameter Encoding(application/x-www-form-urlencode)
AFHTTPSessionManager *manger=[AFHTTPSessionManager manager];
manger.requestSerializer = [AFHTTPRequestSerializer serializer];
[manger POST:URLString parameters:parameters headers:nil progress:nil success:nil failure:nil];
2、JSON Parameter Encoding(application/json)
AFHTTPSessionManager *manger=[AFHTTPSessionManager manager];
manger.requestSerializer = [AFJSONRequestSerializer serializer];
[manger POST:URLString parameters:parameters headers:nil progress:nil success:nil failure:nil];
- 3、multipart/form-data
文件上传时,必须使用的文件编码格式
[request setValue:@"multipart/form-data; boundary=分割线" forHTTPHeaderField:@"Content-Type”];
必须设置这样的请求头,才能进行文件上传。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSDictionary *dict = @{
@"username":@“abcdef”
};
[manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id _Nonnull formData) {
NSData *imageData = [NSData dataWithContentsOfFile:@"/Users/xiaomage/Desktop/Snip20161127_246.png”];
//处理要上传的文件
/* 参数说明
*
* 第一个参数:要上传文件的二进制数据
* 第二个参数:具体参数值file。 和username一样,去作为一个key,服务器规定的。一般写”file”
* 第三个参数:文件的名称
* 第四个参数:文件的二进制数据类型
*/
[formData appendPartWithFileData:imageData name:@"file" fileName:@"123.png" mimeType:@"image/png”];
} progress:nil success:nil failure:nil];
- 4、补充
作为一个ios开发者,你可能会听到别人form表单提交、表单提交,这是千万别慌。form表单其实是就是一个html标签,经常会用来提交网络请求的,仅此而已。你不要误以为表单提交是另一种什么的网编码技术。下面是一个html的form表单示例,enctype属性是设置请求体的数据格式
Title