http那些事

栏目: 后端 · 前端 · 发布时间: 7年前

内容简介:http那些事

简介

超文本传输协议,这决定了协议传输的内容。

如果你想了解一个http协议,就用一门语言基于socket包写一个特定的响应,然后基于浏览器访问它。

http1.1

基于node.js socket写一个简单的http server

require('net').createServer(function(sock) {
    sock.on('data', function(data) {
        sock.write('HTTP/1.1 200 OK\r\n');
        sock.write('\r\n');
        sock.write('hello world!');
        sock.destroy();
    });
}).listen(9090, '127.0.0.1');

scala版本

object SocketServer {
    def main(args: Array[String]): Unit = {
        try {
            val listener = new ServerSocket(8080);
            val socket = listener.accept()
            val data = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nhello world!"
            socket.getOutputStream.write(data.getBytes())
            socket.close()
            listener.close()
        }
        catch {
            case e: IOException =>
                System.err.println("Could not listen on port: 80.");
                System.exit(-1)
        }
    }
}

long polling

http long-polling(推送),服务端故意不响应(一段时间),也不断连接。参见 面试时如何优雅的谈论HTTP/1.0/1.1/2.0

Content-Encoding

http协议中有 Content-Encoding(内容编码)。Content-Encoding 通常用于对实体内容进行压缩编码,目的是优化传输,例如用 gzip 压缩文本文件,能大幅减小体积。内容编码通常是选择性的,例如 jpg / png 这类文件一般不开启,因为图片格式已经是高度压缩过的。

内容编码针对的只是传输正文。在 HTTP/1 中,头部始终是以 ASCII 文本传输,没有经过任何压缩,这个问题在 HTTP/2 中得以解决。

Transfer-Encoding

参见 HTTP 协议中的 Transfer-Encoding

Transfer-Encoding 用来改变报文格式。这涉及到一个通信协议的重要问题:如何定义协议数据的边界

  1. 发送完就断连接(非持久连接)
  2. 协议头部设定content-length
  3. 以特殊字符结尾

content-length有几个问题:

  • 发送数据时,对某些场景,计算数据长度本身是一个比较耗时的事情,同时会占用一定的memory。
  • 接收数据时,从协议头拿到数据长度,接收不够这个长度的数据,就不能解码后交给上层处理。

Transfer-Encoding 当下只有一个可选值:分块编码(chunked)。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。

require('net').createServer(function(sock) {
    sock.on('data', function(data) {
        sock.write('HTTP/1.1 200 OK\r\n');
        sock.write('Transfer-Encoding: chunked\r\n');
        sock.write('\r\n');

        sock.write('b\r\n');
        sock.write('01234567890\r\n');

        sock.write('5\r\n');
        sock.write('12345\r\n');

        sock.write('0\r\n');
        sock.write('\r\n');
    });
}).listen(9090, '127.0.0.1');

server push

服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确地请求。

http2

HTTP/2协议–特性扫盲篇

复用

复用是http2许多特性的起点,因为一个域名只可以使用一个连接,所以在连接之上提出stream的概念,一个stream一般代表一个业务。一个stream可以收发多次请求响应,每次是一个消息(消息的定义是语义上的),一个消息包括多个帧(比如header frame和data frame)。

反过来说, http作为双工通信,必须是一个“相互对应的”request和response才完整。

  1. http1.0 一个请求一个新连接,我发出的是reqeust,我收到的是response,连接关闭,response接收完毕,对应关系自然建立。但因为发送的时候不能接受数据,(服务端未收到请求,自然不知道如何响应),基本是单工通信。
  2. http1.1 多个请求复用连接,但要求server必须按照request的顺序返回response,对应关系也可以建立起来。

很明显,理想状态应该是

  1. client 按需发request,server按处理能力返回response,通过额外的手段将两者关联起来(一般通过一个id)
  2. 不必非得整收整发。此处与上文的分块传输类似,http2做的更加彻底,一个是分块可以是二进制。再则,http1.1分块只是解决了边界问题,http2则应该是在分块(frame)的粒度进行数据编解码。

至于http2的代码展示,因为在浏览器执行url前,还有一次协议协商过程(浏览器最初以http1.1协议发起请求,和server协商一致后转用http2),不好模拟,所以作罢。参见 HTTP/2协议–特性扫盲篇

https

来自《http权威指南》

对web服务器发起请求时,我们需要一种方式来告知web服务器去执行http的安全协议版本,这是通过url中设定http或https来实现的。

  1. 如果是http,客户端就会打开一条到服务器80端口的连接
  2. 如果是https,客户端就会打开一条到服务器443端口的连接,一旦建立连接,client和server就会初始化ssl layer,对加密参数进行沟通,并交换密钥。ssl握手完成之后, ssl layer初始化完成了。 剩下的就是,browser将数据从http layer发到tcp layer之前,要经过ssl layer加密。

以上所述就是小编给大家介绍的《http那些事》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP实战

PHP实战

Dagfinn Reiersol、Marcus Baker、Chris Shiflett / 张颖 等、段大为 审校 / 人民邮电出版社 / 2010-01 / 69.00元

“对于那些想要在PHP方面更进一步的开发者而言,此书必不可少。” ——Gabriel Malkas, Developpez.com “简而言之,这是我所读过的关于面向对象编程和PHP最好的图书。……强烈推荐此书,绝不要错过!” ——Amazon评论 “此书是理论与实践的完美融合,到目前为止,其他任何图书都无法与它相媲美。如果5颗星是满分,它完全值得10颗星!” ——A......一起来看看 《PHP实战》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具