HTTP深入底层探究【高级篇】

1. HTTP各版本的区别

HTTP1.0

特点:默认短链接,明文传输

HTTP1.1

特点: 默认长连接
处理过程:支持管道通信(串行请求),发送完一个请求,不必等待另一个回来,可以继续发送下一个
缺点:服务器按照顺序响应,如果前面的请求处理耗时,后面的请求边会延迟处理,形成队头阻塞

HTTP2.0

1.HPACK 算法:客户端与服务端各维护header字段表,发送的是header索引
2.头信息帧和数据帧, 接收方不需要在对明文转二进制,可以直接解析二进制数据。
3.多路复用:数据包不再按照顺序发出,一个连接可以发送多个请求和响应
每个包叫做数据流,每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数
移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率。
4.支持设置请求优先级
5.服务器主动发送数据给客户端
6.由于浏览器要求只有支持了https的网站才能升级HTTP2.0,所以也可以从这个角度说成,HTTP2.0 基于HTTPS,是安全的。
缺点:多个HTTP请求复用一个tcp 连接,如果发送丢包,就会触发TCP丢包重传的机制,所有的请求,都要等待丢的包回来再继续

HTTP3.0

传输层的TCP,换成了UDP。UDP 是不管顺序和不管丢包的,所以不会出现队头阻塞和丢包阻塞。
UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响。
QUIC 是一个在 UDP 之上的伪 TCP + TLS + HTTP/2 的多路复用的协议。
QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题。所以 HTTP/3 现在普及的进度非常的缓慢.

HTTP3.0

总结

HTTP1.0-HTTP3.0

2.HTTP

HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」

HTTP

「200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。
「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
「206 Partial Content」是应用于 HTTP 分块下载或断电续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
「302 Moved Permanently」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。
「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
「503 Service Unavailable」表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。

常见字段

host: 域名

Connection 字段最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。
HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为 Keep-Alive。
Connection: keep-alive
Accept 字段, 客户端声明自己可以接受哪些数据格式。
Accept: / 可以接受任何格式的数据。
Accept-Encoding 字段说明自己可以接受哪些压缩方法
Accept-Encoding: gzip, deflate
Content-Type:告诉服务端,本次数据是什么格式(表单、文件、json/xml)
application/x-www-form-urlencoded:主要向服务器提交用户隐私相关的信息(浏览器支持)
multipart/form-data: 向服务器上传小文件(浏览器支持)
application/json:向后台服务器提交结构化数据(RESTful 设计风格需要)
text/xml 向后台服务器提交结构化数据(RESTful 设计风格需要)
application/octet-stream(8进制流),如果不想告诉服务器具体的文件类型,可以使用这个 Content-Type

Content-Length: 服务器返回给客户端数据的时候,告诉数据占多少字节
Content-Length: 1000, 数据占1000字节
Content-Type 字段用于服务器回应时,告诉客户端,本次数据是什么格式。(html/json/xml/图片、音频、视频、zip等 )
Content-Type: text/html; charset=utf-8, 发送的是网页,而且编码是UTF-8。
text/plain
image/jpg
image/png
image/gif
text/html
application/json
Content-Encoding 字段说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式

HTTP

post/get

get 获取数据
不会修改服务器的资源,所以是安全的。
每次操作的结果都一样,所以是幂等的。
GET请求能够被缓存, 会保存在 Cache 目录中 \bundleId 下 Cache.db 中
cfurl_cache_receiver_data,缓存所有的请求数据
cfurl_cache_response,缓存所有的响应
不能发送敏感数据,请求大小限制在2-8k
URL 字符串中如果包含中文、空格,需要添加百分号转义[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
post 发送数据,并且接收响应,会对服务器的资源有影响,所以是不安全的,
由于每次post 都会创建或者修改资源,所以也不是幂等的。
不能被缓存,发送敏感数据,安全,请求大小依赖于服务器的设置,一般PHP = 2M
上传文件:
请求格式

OC:
Content-Type: multipart/form-data; boundary=boundary

上传的数据格式

//// ------ 单个文件上传 -------

// name 服务器对应的字段名;filename 上传到服务器后的名字
--boundary
Content-Disposition: form-data; name="userfile"; filename="aaa.txt"
Content-Type: application/octet-stream
....要上传文件的二进制数据 ...
--boundary-- 
    
//// ------ 多个文件上传 -------
--boundary
Content-Disposition: form-data; name="userfile[]"; filename="aaa.txt"
Content-Type: application/octet-stream

....要上传文件的二进制数据 ...


--boundary
Content-Disposition: form-data; name="userfile[]"; filename="aaa副本.txt"
Content-Type: application/octet-stream

....要上传文件的二进制数据 ...

--boundary
// status 是脚本文件接收参数的名称
Content-Disposition: form-data; name="status"

....要上传文件的二进制数据 ...

--boundary--

上传一个文件:

OC:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"001.png" withExtension:nil];
    NSData *data = [NSData dataWithContentsOfURL:fileURL];

    [self uploadFile:@"userfile" fileName:@"abc" fileData:data];
}

///  上传单个文件
///
///  @param fieldName 服务器自短命
///  @param fileName  文件名
///  @param fileData  上传文件二进制数据
- (void)uploadFile:(NSString *)fieldName fileName:(NSString *)fileName fileData:(NSData *)fileData {
    // 1. url - 负责上传的脚本
    NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload.php"];

    // 2. request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";

    NSString *typeValue = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:typeValue forHTTPHeaderField:@"Content-Type"];

    request.HTTPBody = [self formData:fieldName fileName:fileName fileData:fileData];

    // 3. connection
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]);
    }];
}


///  生成 formData 二进制数据
///
///  @param fieldName 服务器字段名
///  @param fileName  文件名
///  @param fileData  上传文件二进制数据
///
///  @return formData 二进制数据
- (NSData *)formData:(NSString *)fieldName fileName:(NSString *)fileName fileData:(NSData *)fileData {

    NSMutableData *dataM = [NSMutableData data];

    // 拼接数据
    NSMutableString *strM = [NSMutableString string];

    [strM appendFormat:@"--%@\r\n", boundary];
    [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, fileName];
    [strM appendString:@"Content-Type: application/octet-stream\r\n\r\n"];

    [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]];
    [dataM appendData:fileData];

    NSString *tail = [NSString stringWithFormat:@"\r\n--%@--", boundary];
    [dataM appendData:[tail dataUsingEncoding:NSUTF8StringEncoding]];

    return dataM.copy;
}

青山不改,绿水长流,后会有期,感谢每一位佳人的支持!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容