2.1.http.md.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <meta http-equiv="Content-Style-Type" content="text/css" />
  6. <meta name="generator" content="pandoc" />
  7. <title></title>
  8. <style type="text/css">code{white-space: pre;}</style>
  9. <style type="text/css">
  10. div.sourceCode { overflow-x: auto; }
  11. table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
  12. margin: 0; padding: 0; vertical-align: baseline; border: none; }
  13. table.sourceCode { width: 100%; line-height: 100%; }
  14. td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
  15. td.sourceCode { padding-left: 5px; }
  16. code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
  17. code > span.dt { color: #902000; } /* DataType */
  18. code > span.dv { color: #40a070; } /* DecVal */
  19. code > span.bn { color: #40a070; } /* BaseN */
  20. code > span.fl { color: #40a070; } /* Float */
  21. code > span.ch { color: #4070a0; } /* Char */
  22. code > span.st { color: #4070a0; } /* String */
  23. code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
  24. code > span.ot { color: #007020; } /* Other */
  25. code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
  26. code > span.fu { color: #06287e; } /* Function */
  27. code > span.er { color: #ff0000; font-weight: bold; } /* Error */
  28. code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  29. code > span.cn { color: #880000; } /* Constant */
  30. code > span.sc { color: #4070a0; } /* SpecialChar */
  31. code > span.vs { color: #4070a0; } /* VerbatimString */
  32. code > span.ss { color: #bb6688; } /* SpecialString */
  33. code > span.im { } /* Import */
  34. code > span.va { color: #19177c; } /* Variable */
  35. code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
  36. code > span.op { color: #666666; } /* Operator */
  37. code > span.bu { } /* BuiltIn */
  38. code > span.ex { } /* Extension */
  39. code > span.pp { color: #bc7a00; } /* Preprocessor */
  40. code > span.at { color: #7d9029; } /* Attribute */
  41. code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
  42. code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
  43. code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
  44. code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
  45. </style>
  46. <link rel="stylesheet" href="css/vendor.css" type="text/css" />
  47. </head>
  48. <body>
  49. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wb="http://open.weibo.com/wb" >
  50. <head>
  51. <title>一步步搭建物联网系统(教你设计物联网系统)</title>
  52. <meta name="keywords" content="设计物联网系统,物联网系统设计">
  53. <meta name="description" content="一份关于如何设计物联网系统的文档">
  54. <link rel="stylesheet" href="../css/vendor.css" />
  55. </head>
  56. <body class="container inner wrap">
  57. <h1>一步步搭建物联网系统(教你设计物联网系统)</h1>
  58. </body>
  59. </html>
  60. <div id="TOC">
  61. <ul>
  62. <li><a href="#http-熟悉陌生"><span class="toc-section-number">1</span> HTTP 熟悉&amp;陌生</a><ul>
  63. <li><a href="#你所没有深入的http"><span class="toc-section-number">1.1</span> 你所没有深入的HTTP</a><ul>
  64. <li><a href="#打开网页时发生了什么"><span class="toc-section-number">1.1.1</span> 打开网页时发生了什么</a></li>
  65. <li><a href="#url组成"><span class="toc-section-number">1.1.2</span> URL组成</a></li>
  66. </ul></li>
  67. <li><a href="#一次http-get请求"><span class="toc-section-number">1.2</span> 一次HTTP GET请求</a><ul>
  68. <li><a href="#http响应"><span class="toc-section-number">1.2.1</span> HTTP响应</a></li>
  69. </ul></li>
  70. </ul></li>
  71. </ul>
  72. </div>
  73. <h1 id="http-熟悉陌生"><span class="header-section-number">1</span> HTTP 熟悉&amp;陌生</h1>
  74. <h2 id="你所没有深入的http"><span class="header-section-number">1.1</span> 你所没有深入的HTTP</h2>
  75. <p>Internet有两个核心协议: IP和TCP,这样讲述起来似乎会很漫长。</p>
  76. <p>基本概念</p>
  77. <blockquote>
  78. <p>超文本传输协议 (HTTP-Hypertext transfer protocol) 是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。</p>
  79. </blockquote>
  80. <ul>
  81. <li>HTTP是用于客户端与服务端之间的通信。</li>
  82. <li>传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的。</li>
  83. </ul>
  84. <p><code>注意</code>: HTTP协议只规定了客户端与服务端的通信规则,而没有规定其通讯协议,只是现在的大部分实现都是将TCP作为通讯协议。</p>
  85. <h3 id="打开网页时发生了什么"><span class="header-section-number">1.1.1</span> 打开网页时发生了什么</h3>
  86. <p>简单地来说,当我们在浏览器上输入URL的敲下回车的时候。</p>
  87. <ul>
  88. <li>浏览器需要查找域名<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a>的IP,从不同的缓存直至DNS服务器。</li>
  89. <li>浏览器会给web服务器发送一个HTTP请求</li>
  90. <li>服务器“处理”请求</li>
  91. <li>服务器发回一个HTML响应</li>
  92. <li>浏览器渲染HTML到页面。</li>
  93. </ul>
  94. <p>在<a href="http://stackoverflow.com/questions/2092527/what-happens-when-you-type-in-a-url-in-browser">StackOverflow</a>上有一个这样的回答会比较详细。</p>
  95. <ul>
  96. <li>browser checks cache; if requested object is in cache and is fresh, skip to #9</li>
  97. <li>browser asks OS for server’s IP address</li>
  98. <li>OS makes a DNS lookup and replies the IP address to the browser</li>
  99. <li>browser opens a TCP connection to server (this step is much more complex with HTTPS)</li>
  100. <li>browser sends the HTTP request through TCP connection</li>
  101. <li>browser receives HTTP response and may close the TCP connection, or reuse it for another request</li>
  102. <li>browser checks if the response is a redirect (3xx result status codes), authorization request (401), error (4xx and 5xx), etc.; these are handled differently from normal responses (2xx)</li>
  103. <li>if cacheable, response is stored in cache</li>
  104. <li>browser decodes response (e.g. if it’s gzipped)</li>
  105. <li>browser determines what to do with response (e.g. is it a HTML page, is it an image, is it a sound clip?)</li>
  106. <li>browser renders response, or offers a download dialog for unrecognized types</li>
  107. </ul>
  108. <p>忽略一些细节便剩下了</p>
  109. <ol style="list-style-type: decimal">
  110. <li>从浏览器输入URL</li>
  111. <li>浏览器找到服务器,服务器返回HTML文档</li>
  112. <li>从对应的服务器下载资源</li>
  113. </ol>
  114. <p>说说第一步,开始时我们输入的是URI(统一资源标识符,Uniform Resource Identifier),它还有另外一个名字叫统一资源定位器(URL<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a>,Uniform Resource Locator)。</p>
  115. <h3 id="url组成"><span class="header-section-number">1.1.2</span> URL组成</h3>
  116. <p>网址算是URL的一个俗称,让我们来看看一个URL的组成,以HTTP版IOT中的URL为例。</p>
  117. <p><code>http://b.phodal.com/athome/1</code></p>
  118. <p>开始之前,我们需要标出URL的80端口以及json文件的全称,那么上面的网址就会变成</p>
  119. <p><code>http://b.phodal.com:80/athome/1.json</code></p>
  120. <p>那么对于这个URL的就有下面几部分组成</p>
  121. <ul>
  122. <li><code>http://</code> http说的是这个URL用的是HTTP协议,至于<code>//</code>是一个分隔符,用法和C语言中的<code>;</code>一样。这样的协议还可以是coap,https,ftp等等。</li>
  123. <li><code>b</code> 是子域名,一个域名在<strong>允许</strong>的情况下可以有不限数量的子域名。</li>
  124. <li><code>phodal.com</code> 代表了一个URL是phodal.com下面的域名</li>
  125. <li><code>80</code> 80是指80端口,默认的都是80,对于一个不是80端口的URL应该是这样的<code>http://iot-coap.phodal.com:8896/</code></li>
  126. <li><code>athome</code> 指的是虚拟目录部分,或者文件路径</li>
  127. <li><code>1.json</code>看上去就是一个文件名,然而也代表着这是一个资源。</li>
  128. </ul>
  129. <p>对就一个稍微复杂点的例子就是</p>
  130. <p><code>http://ebook.designiot.cn/#你所没有深入的http</code></p>
  131. <p>这里的<code>#</code>后面是锚部分,如果你打开这个URL就会发现会直接跳转到相应的锚部分,对就于下面这样的一个例子来说</p>
  132. <p><code>http://www.phodal.com/search/?q=iot&amp;type=blog</code></p>
  133. <p><code>?</code>后面的<code>q=iot&amp;type=blog</code>的部分是参数部分,通常用于查询或者、搜索。</p>
  134. <h2 id="一次http-get请求"><span class="header-section-number">1.2</span> 一次HTTP GET请求</h2>
  135. <p>当我们打开最小物联网系统的一个页面时,如<a href="http://b.phodal.com/athome/1.json" class="uri">http://b.phodal.com/athome/1.json</a></p>
  136. <p>我们在浏览器上看到的结果是</p>
  137. <div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript">[
  138. <span class="op">{</span>
  139. <span class="st">&quot;id&quot;</span><span class="op">:</span> <span class="dv">1</span><span class="op">,</span>
  140. <span class="st">&quot;temperature&quot;</span><span class="op">:</span> <span class="dv">19</span><span class="op">,</span>
  141. <span class="st">&quot;sensors1&quot;</span><span class="op">:</span> <span class="dv">31</span><span class="op">,</span>
  142. <span class="st">&quot;sensors2&quot;</span><span class="op">:</span> <span class="fl">7.5</span><span class="op">,</span>
  143. <span class="st">&quot;led1&quot;</span><span class="op">:</span> <span class="dv">0</span>
  144. <span class="op">}</span>
  145. ]</code></pre></div>
  146. <p>只是我们看到的是结果,忽略了这其中的过程,于是我们用curl<a href="#fn3" class="footnoteRef" id="fnref3"><sup>3</sup></a>命令来看看详细的情况。</p>
  147. <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">curl</span> -I -s http://b.phodal.com/athome/1.json</code></pre></div>
  148. <p>出于某种原因考虑,删去了其中一些元素,剩下下面这些。</p>
  149. <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">HTTP/1.1</span> 200 OK
  150. <span class="kw">Content-Type</span>: application/json
  151. <span class="kw">Date</span>: Fri, 05 Sep 2014 15:05:49 GMT
  152. [<span class="dt">{&quot;id&quot;:1,&quot;temperature&quot;:19,&quot;sensors1&quot;:31,&quot;sensors2&quot;:7.5,&quot;led1&quot;:0}</span>]</code></pre></div>
  153. <p>我们用curl命令向服务器发起了GET请求,服务器返回了上面的结果。</p>
  154. <h3 id="http响应"><span class="header-section-number">1.2.1</span> HTTP响应</h3>
  155. <p>一个HTTP响应由三部分组成</p>
  156. <ul>
  157. <li>状态行(状态码)</li>
  158. <li>消息报头(响应报头)</li>
  159. <li>响应正文(消息体)</li>
  160. </ul>
  161. <h4 id="http响应-状态码"><span class="header-section-number">1.2.1.1</span> HTTP响应 状态码</h4>
  162. <p>在上面的结果中,状态行是</p>
  163. <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">HTTP/1.1</span> 200 OK</code></pre></div>
  164. <p>返回的状态码是200,OK是状态码的原因短语。</p>
  165. <p>如果是一个跳转的页面,它就可能是下面的结果:</p>
  166. <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">HTTP/1.0</span> 301 MOVED PERMANENTLY
  167. <span class="kw">Date</span>: Mon, 08 Sep 2014 12:04:01 GMT
  168. <span class="kw">Content-Type</span>: text/html<span class="kw">;</span> <span class="ot">charset=</span>utf-8 </code></pre></div>
  169. <p>HTTP Status有五种状态,而这五种状态又有所细分,提一下这五种状态,详细可参见<a href="http://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81">http://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81</a></p>
  170. <ul>
  171. <li>1xx消息</li>
  172. <li>2xx成功</li>
  173. <li>3xx重定向</li>
  174. <li>4xx客户端错误</li>
  175. <li>5xx服务器错误</li>
  176. </ul>
  177. <p>如</p>
  178. <ul>
  179. <li>200 ok - 成功返回状态,对应,GET,PUT,PATCH,DELETE.</li>
  180. <li>201 created - 成功创建。</li>
  181. <li>304 not modified - HTTP缓存有效。</li>
  182. <li>400 bad request - 请求格式错误。</li>
  183. <li>401 unauthorized - 未授权。</li>
  184. <li>403 forbidden - 鉴权成功,但是该用户没有权限。</li>
  185. <li>404 not found - 请求的资源不存在</li>
  186. <li>405 method not allowed - 该http方法不被允许。</li>
  187. <li>410 gone - 这个url对应的资源现在不可用。</li>
  188. <li>415 unsupported media type - 请求类型错误。</li>
  189. <li>422 unprocessable entity - 校验错误时用。</li>
  190. <li>429 too many request - 请求过多。</li>
  191. </ul>
  192. <h4 id="http响应-响应报头"><span class="header-section-number">1.2.1.2</span> HTTP响应 响应报头</h4>
  193. <p>在这次响应中,返回了两个报头,即</p>
  194. <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">Content-Type</span>: application/json
  195. <span class="kw">Date</span>: Fri, 05 Sep 2014 15:05:49 GMT</code></pre></div>
  196. <p>Content-Type和Date,在这里的Context-Type是application/json,而通常情况下我们打开一个网站时,他的Content-Type应该是text/html。</p>
  197. <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">Content-Type</span>: text/html<span class="kw">;</span></code></pre></div>
  198. <p>Content-Type是最重要的报头。</p>
  199. <h4 id="http响应-响应正文"><span class="header-section-number">1.2.1.3</span> HTTP响应 响应正文</h4>
  200. <p>正文才是我们真正想要的内容,上面的都是写给浏览器看的,一般的人不会去关注这些。</p>
  201. <div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript">HTTP/<span class="fl">1.1</span> <span class="dv">200</span> OK
  202. Server<span class="op">:</span> <span class="va">phodal</span>.<span class="at">com</span>/<span class="fl">0.17.5</span>
  203. Content<span class="op">-</span>Type<span class="op">:</span> application/json
  204. [<span class="op">{</span><span class="st">&quot;id&quot;</span><span class="op">:</span><span class="dv">1</span><span class="op">,</span><span class="st">&quot;temperature&quot;</span><span class="op">:</span><span class="dv">19</span><span class="op">,</span><span class="st">&quot;sensors1&quot;</span><span class="op">:</span><span class="dv">31</span><span class="op">,</span><span class="st">&quot;sensors2&quot;</span><span class="op">:</span><span class="fl">7.5</span><span class="op">,</span><span class="st">&quot;led1&quot;</span><span class="op">:</span><span class="dv">0</span><span class="op">}</span>]</code></pre></div>
  205. <p>通常这是以某种格式写的,在这里是以JSON写的,而对于一个网站的时候则是HTML,如:</p>
  206. <div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;html&gt;</span>
  207. <span class="kw">&lt;head&gt;</span>
  208. <span class="kw">&lt;meta</span><span class="ot"> charset=</span><span class="st">&quot;UTF-8&quot;</span><span class="kw">&gt;</span>
  209. <span class="kw">&lt;title&gt;</span>Document<span class="kw">&lt;/title&gt;</span>
  210. <span class="kw">&lt;/head&gt;</span>
  211. <span class="kw">&lt;body&gt;</span>
  212. <span class="kw">&lt;/body&gt;</span>
  213. <span class="kw">&lt;/html&gt;</span> </code></pre></div>
  214. <p>那么这次GET请求返回的就是:</p>
  215. <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">HTTP/1.0</span> 200 OK
  216. <span class="kw">Date</span>: Mon, 08 Sep 2014 12:04:01 GMT
  217. <span class="kw">Content-Type</span>: text/html<span class="kw">;</span> <span class="ot">charset=</span>utf-8
  218. <span class="kw">&lt;html&gt;</span>
  219. <span class="kw">&lt;head&gt;</span>
  220. <span class="kw">&lt;meta</span> charset=<span class="st">&quot;UTF-8&quot;</span><span class="kw">&gt;</span>
  221. <span class="kw">&lt;title&gt;</span>Document<span class="kw">&lt;</span>/title<span class="kw">&gt;</span>
  222. <span class="kw">&lt;</span>/<span class="kw">head&gt;</span>
  223. <span class="kw">&lt;body&gt;</span>
  224. [<span class="dt">{&quot;id&quot;:1,&quot;temperature&quot;:19,&quot;sensors1&quot;:31,&quot;sensors2&quot;:7.5,&quot;led1&quot;:0}</span>]
  225. <span class="kw">&lt;</span>/<span class="kw">body&gt;</span>
  226. <span class="kw">&lt;</span>/<span class="kw">html&gt;</span> </code></pre></div>
  227. <p>虽然与第一次请求的结果在游览器上看似乎是一样的(ps:可能有微小的差异),然而其本质是不同的。</p>
  228. <p>推荐及参考书目:</p>
  229. <ul>
  230. <li>《Web性能权威指南》</li>
  231. <li>《图解HTTP》</li>
  232. <li>《RESTful Web Services Cookbook》</li>
  233. <li>《RESTful Web APIs》</li>
  234. </ul>
  235. <div class="footnotes">
  236. <hr />
  237. <ol>
  238. <li id="fn1"><p>形如http://www.phodal.com<a href="#fnref1">↩</a></p></li>
  239. <li id="fn2"><p>URL 是 URI 的子集<a href="#fnref2">↩</a></p></li>
  240. <li id="fn3"><p>curl是利用URL语法在命令行方式下工作的开源文件传输工具。<a href="#fnref3">↩</a></p></li>
  241. </ol>
  242. </div>
  243. </body>
  244. </html>