转载测试

<div class="htmledit_views" id="content_views">
                
<p></p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-340caa79e7d65854.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<blockquote>
<p>引言:作为一名软件工程Web专业学生,对于HTTP的熟悉掌握是必不可少的,特此做记录,打造自己的HTTP栈。</p>
</blockquote>
<h2><a name="t0"></a>URL与URI</h2>
<p></p>
<p>我们经常接触到的就是URL了,它就是我们访问web的一个字符串地址,那么URI是什么呢?他们是什么关系呢?<br>
URL:uniform resource location 统一资源定位符<br>
URI:uniform resource identifier 统一资源标识符<br>
这也就是说,URI是一种资源的标识;而URL也是一种URI,也是一种资源的标识,但它也指明了如何定位Locate到这个资源。<br>
URI是一种抽象的资源标识,<strong>既可以是绝对的,也可以是相对的</strong>。但是URL是一种URI,它指明了定位的信息,必须是绝对的。</p>
<h2><a name="t1"></a>报文-通信的桥梁</h2>
<p>客户端和服务器端通过相互发送<strong>报文</strong>进行通信,要深刻理解HTTP协议,就需要理解报文的格式和内容。</p>
<h3><a name="t2"></a>报文的组成</h3>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-384323e63add5cd5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<p><br>
无论是请求报文还是响应报文都需要有报文首部,当然报文主体并不是必需的。<br>
一般来说,请求报文的格式如下:</p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-7129daf6bf693d8b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<p><br>
看一下百度网站的请求报文:</p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-2d2f07356575b586.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<p><br>
简单的报文形式:</p>
<pre onclick="hljs.copyCode(event)"><code class="language-cpp hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">GET / HTTP/<span class="hljs-number"><span class="hljs-number">1.1</span></span>    <span class="hljs-comment"><span class="hljs-comment">//请求行,包含用于请求的方法,请求的URI,HTTP版本</span></span></code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp"><span class="hljs-comment"><span class="hljs-comment">//以下为各种首部字段</span></span></code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Host: www.baidu.com</code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Connection: keep-alive</code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Upgrade-Insecure-Requests: <span class="hljs-number"><span class="hljs-number">1</span></span></code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">User-Agent: Mozilla/<span class="hljs-number"><span class="hljs-number">5.0</span></span>...</code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Accept-Encoding: gzip, deflate, sdch</code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Accept-Language: zh-CN,zh;q=<span class="hljs-number"><span class="hljs-number">0.8</span></span></code></div></div></li></ol></code><div class="hljs-button {2}" data-title="复制"></div></pre>
<p>响应报文的格式如下:</p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-c1beffca0f00b20f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<p><br>
看一下百度网站的响应报文:</p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-31f3af6aa3405976.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<pre onclick="hljs.copyCode(event)"><code class="language-cpp hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">HTTP/<span class="hljs-number"><span class="hljs-number">1.1</span></span> <span class="hljs-number"><span class="hljs-number">200</span></span> OK   <span class="hljs-comment"><span class="hljs-comment">//状态行,包含表明响应结果的状态码,原因短语和HTTP版本</span></span></code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp"><span class="hljs-comment"><span class="hljs-comment">//以下为各种首部字段</span></span></code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Server: bfe/<span class="hljs-number"><span class="hljs-number">1.0</span></span><span class="hljs-number"><span class="hljs-number">.8</span></span><span class="hljs-number"><span class="hljs-number">.5</span></span></code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Date: Tue, <span class="hljs-number"><span class="hljs-number">06</span></span> Oct <span class="hljs-number"><span class="hljs-number">2015</span></span> <span class="hljs-number"><span class="hljs-number">14</span></span>:<span class="hljs-number"><span class="hljs-number">48</span></span>:<span class="hljs-number"><span class="hljs-number">28</span></span> GMT</code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Content-Type: text/html;charset=utf<span class="hljs-number">-</span><span class="hljs-number"><span class="hljs-number">8</span></span></code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Transfer-Encoding: chunked</code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Connection: keep-alive</code></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><code class="cpp">Cache-Control: <span class="hljs-keyword"><span class="hljs-keyword">private</span></span></code></div></div></li></ol></code><div class="hljs-button {2}" data-title="复制"></div></pre>
<h2><a name="t3"></a>告知服务器意图的HTTP方法</h2>
<p>发送HTTP的方法有许多种,最常用的便是GET和POST,下面就这两种进行详细地说明。</p>
<ol><li><strong>GET</strong><br>
GET方法用来请求访问URI所指定的资源,<strong>(我想访问你的某个资源)</strong>并不对服务器上的内容产生任何作用结果;每次GET的内容都是相同的。GET方式把请求所需要的参数放到<code>URL</code>中,直接就可以在URL中看见,有大小限制。</li><li><strong>POST</strong><br>
POST方法用来传输实体主体,目的并不是获取响应的主体内容,<strong>(我要把这条信息告诉你)</strong>,POST方式则是把内容放在<code>报文内容</code>中,因此只要报文的内容没有限制,它的大小就没有限制。</li><li><strong>总结</strong><br>
GET用于获取某个内容,POST用于提交某种数据请求。<br>
按照使用场景来说,一般用户注册的内容属于私密的,这应该使用POST方式;而针对某一内容的查询,为了快速的响应,可以使用GET方式。</li></ol><h2><a name="t4"></a>无状态协议与Cookie</h2>
<p>HTTP是一种无状态协议,也就是每一次发送都是一次新的开始,服务器并不知道也没有必要知道当前连接的客户端是否之前有过交集,那么当需要进行保存用户登录状态时,则出现了麻烦,这个时候使用Cookie来保存状态。<br>
Cookie会根据服务器端发送的响应报文内的一个叫做<strong>Set-Cookie</strong>的首部字段,通知客户端保存Cookie(保存在自己的电脑里),当下次客户端发送请求时,<strong>Cookie值会被添加到请求报文中发送出去。</strong></p>
<h2><a name="t5"></a>持久连接</h2>
<p>使用浏览器浏览一个包含多张图片的HTML页面时,浏览器会发起多次请求,如图所示:</p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-4de98a5a646df99c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<p><br>
显而易见每次请求会造成<strong>无谓的TCP连接建立和断开,增加通信量的开销。</strong></p>
<h4>引入持久连接</h4>
<p>持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。目前HTTP/1.1中默认为持久连接。</p>
<pre onclick="hljs.copyCode(event)"><code class="language-ruby hljs"><code class="ruby"><span class="hljs-constant"><span class="hljs-symbol">Connection</span></span><span class="hljs-symbol"><span class="hljs-symbol">:</span>keep-alive</span></code></code><div class="hljs-button {2}" data-title="复制"></div></pre>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-219f8b2c3fa40a3b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<h2><a name="t6"></a>管线化</h2>
<p>管线化可以同时并行发送多个请求,不需要一个一个等待响应了。</p>
<h2><a name="t7"></a>常见的状态码</h2>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-2fdc0039a218345b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<h2><a name="t8"></a>确保安全的HTTPS</h2>
<p>HTTP+加密+认证+完整性保护 = HTTPS<br>
一些登陆界面和购物结算界面使用HTTPS通信,也就是改用<code>https://</code>,HTTPS说简单点就是它的通信接口部分被SSL和TLS协议代替而已。</p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-5f46616e0d9a802c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<h2><a name="t9"></a>身份认证</h2>
<p>有一些网址或者服务需要用户的身份信息,因此需要随时知道这些消息,但是肯定不能每次都让用户输入用户密码,因此关于认证就有下面几种方式:</p>
<div class="image-package imagebubble"><img src="http://upload-images.jianshu.io/upload_images/101399-ce55d2fc363c60b2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" class="imagebubble-image" alt=""><br><div class="image-caption"></div>
</div>
<p><br>
在这里主要说一下FormBase认证,也就是<strong>表单认证</strong>。</p>
<h4>使用Cookie来管理Session</h4>
<ol><li>客户端把用户IE和密码等登录信息放入报文的实体部分,以<strong>POST</strong>方式发送给服务器。</li><li>服务器进行身份认证,产生SessionID,加入到Set-Cookie内,返回给客户端。</li><li>客户端接收到SessionID后,将其加入Cookie,下次请求时,浏览器会自动发送Cookie。</li></ol><blockquote>
<p>在传输过程中,一种安全地保存密码方式是,先利用给密码加盐的方式增加额外信息,再使用散列hash函数计算出散列值后保存。</p>
</blockquote>
<p>书籍推荐:《图解HTTP》,轻松理解更全面的HTTP知识。</p>
<br><br><div>文/LuckyJing(简书作者)<br>
原文链接:http://www.jianshu.com/p/81632fea327c<br>
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。</div>
<br><p><br></p>
<p><br></p>
            </div>

猜你喜欢

转载自blog.csdn.net/qq_34491826/article/details/89917803