ios随笔学习之HTTP基础

一、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);
}

控制台打印:


截屏2020-12-16 上午10.45.10.png

青花瓷抓包截图:


截屏2020-12-16 上午10.53.55.png
字段名 说明 示例
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<AFMultipartFormData>  _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属性是设置请求体的数据格式
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head>
<body>
 <form  action="http://testct.56cold.com/wechat/user/login"   enctype="application/x-www-form-urlencoded" method=“post”>
     <div>
         <label for="name">用户名:</label>
         <input type="text" id="name" name="username” />
     </div>
     <div>
         <label for="passwd">密码:</label>
         <input type="password" id="passwd" name="password” />
     </div>
     <div>
         <input type="submit" id="submit" name="submit_button" value="提交” />
     </div>
 </form>
</body>
</html>

2.1.4、Range

如果想进行断点下载,我们需要在请求头中设置文件下载的range,告诉服务器,我们需要从文件的哪个位置开始下载。
[request setValue:@"bytes=0-499" forHTTPHeaderField:@"Range”];

  • Range: bytes=0-499 , 表示头500个字节
  • Range: bytes=500-999 , 表示第二个500字节
  • Range: bytes=-500, 表示最后500个字节
  • Range: bytes=500- ,表示500字节以后的范围

2.1.5、Cookie

  • cookie:HTTP Cookie是服务器发送到客户端并保存在本地的一小块数据,它会在客户端下一次向同一服务器再发起请求时被携带并发送到服务器上,以此来维护弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

  • session: Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
    session也是基于cookie进行的,可以说session是另一种cookie

当客户端访问服务器,Service响应后会通过request.getSession()获得一个session对象(如果request没有带JSESSIONID,就会创建新的Session对象;如果request带了JSESSIONID,就会返回对应的Session对象)

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username”);
        String password = request.getParameter("password”);
        response.setContentType("text/html; charset=UTF-8”);
            // 将用户信息存放到Session中
      HttpSession session = request.getSession();
      session.setAttribute("username", username);
       session.setAttribute("password", password);
}

当Service返回数据时,Set-Cookie:JSESSIONID=666会自动添加到响应头上。当客户端再次访问服务器时,客户端也会自动将Cookie:SESSIONID=666携带到请求头上。
现在的http会话都是通过session这样的机制维持状态的,我们这里所说的cookie也就是session-cookie

三、响应头字段

字段 说明 示例
Server 服务器的名字 Apache/2.4.1(unix)
Date 发送消息的日期和时间 Date: Tue,15 Nov 1994 08:12:31 GMT
Content-Type 响应体的类型 text/html;charset=utf-8
Content-Encoding 内容所使用的编码类型 gzip
Content-Length 响应体的长度(字节为单位) 348
Content-Disposition 一个可以让客户端下载文件并建议文件名的头部 attachment;filename=“name.text”
Content-Range 这条消息是属于完整消息的哪一部分 bytes 21010-47021/47022
Last-Modified 所请求的对象的最后修改时间 Tue,15 Nov 1994 12:45:26 GMT
Set-Cookie 返回一个Cookie让客户端保存
Access-Control-Allow-Origin 指定哪些网站可参与到跨来源资源共享过程中 *
Location 用来进行重定向,或者在创建了某个新资源时使用 http://www.w3.org

3.1、重定向

URL 重定向,也称为 URL 转发,是一种当实际资源,如单个页面、表单或者整个 Web 应用被迁移到新的 URL 下的时候,保持(原有)链接可用的技术。HTTP 协议提供了一种特殊形式的响应—— HTTP 重定向(HTTP redirects)来执行此类操作。
通俗地来讲:例如浏览器想要访问http://s.click.taobao.com页面,然而服务器却又返回了https://error.taobao.com/app/tbhome/common/error.html,最终显示了error.html内容

截屏2020-12-21 下午1.55.32.png

    NSString *urlString = @"http://s.click.taobao.com”;
    NSURL *url = [NSURL URLWithString:urlString];
     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
     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{
    NSHTTPURLResponse *respons = (NSHTTPURLResponse *)task.response;
    NSLog(@"%@",respons.allHeaderFields);
    NSLog(@"%ld",(long)respons.statusCode);
    NSLog(@"原始请求:%@",task.originalRequest.URL);
    NSLog(@"现在的请求:%@",task.currentRequest.URL);
}

原始请求:http://s.click.taobao.com。现在的请求:https://error.taobao.com/app/tbhome/common/error.htm,状态码200,请求头并没返回location。要想监听到重定向应该在下面这个方法:

//#pragma mark - 即将重定向时调用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                     willPerformHTTPRedirection:(NSHTTPURLResponse *)response
                                     newRequest:(NSURLRequest *)request
 completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler{
  NSLog(@"原始请求:%@",task.currentRequest.URL);
    completionHandler(request);
    NSLog(@"%@",task.currentRequest.allHTTPHeaderFields);
    NSLog(@"%@",response.allHeaderFields);
  
    NSLog(@"重定向的请求:%@",request.URL);
    NSLog(@"即将重定向时调用”);
    NSLog(@"%ld",(long)response.statusCode);
}
截屏2020-12-21 下午2.58.58.png

原始请求:http://s.click.taobao.com/
重定向的请求:https://error.taobao.com/app/tbhome/common/error.htm
状态码:302
状态码302:请求的资源被暂时的移动到了由Location头部指定的URL上

wkwebview监听重定向的代理方法:

- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
    NSLog(@"原始的url:%@",self.request.URL);
    NSLog(@"发生重定向了的url:%@",webView.URL);
}

只要服务端response的location设置了url,客户端就会发生重定向

四、常见的状态码

状态码可以分为5类
- 1、信息响应:100~199
- 2、成功响应:200~299
- 3、重定向:300~399
- 4、客户端错误:400~499
- 5、服务器错误 :500~599

  • 200 OK:请求成功
  • 302 Found:请求的资源被暂时的移动到了由Location头部指定的URL上
  • 304 Not Modified:说明无需再次传输请求的内容,也就是说可以使用缓存的内容
  • 400 Bad Request:由于语法无效,服务器无法理解该请求
  • 401 Unauthorized:由于缺乏目标资源要求的身份验证凭证
  • 403 Forbidden:服务器端有能力处理该请求,但是拒绝授权访问
  • 404 Not Found:服务器端无法找到所请求的资源
  • 405 Method Not Allowed:服务器禁止了使用当前HTTP方法的请求
  • 406 Not Acceptable:服务器端无法提供与Accept-Charset以及Accept-Language指定的值相匹配的响应
  • 408 Request Timeout:服务器想要将没有在使用的连接关闭
  • 500 Internal Server Error:所请求的服务器遇到意外的情况并阻止其执行请求
  • 501 Not Implemented:请求的方法不被服务器支持,因此无法被处理。
    服务器必须支持的方法(即不会返回这个状态码的方法)只有 GET 和 HEAD
  • 502 Bad Gateway:作为网关或代理角色的服务器,从上游服务器(如tomcat)中接收到的响应是无效的
  • 503 Service Unavailable:服务器尚未处于可以接受请求的状态
    通常造成这种情况的原因是由于服务器停机维护或者已超载
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容