Node.js系列-http

前言:

  最近一直忙着公司項目的事,戰友們的留言也沒空回覆,博客也有段時間沒有更新了,年末了就是一個的忙啊~~~(ps:同感的也給個贊吧)css

  如今前端的就是一直地更新一直有新的東西出來,什麼ES2015,ES2016,到如今已經ES2018了,除了ES語法的更新迭代,JavaScript的強大又html

延伸到了後臺,node.js。只能說學無止境啊,共勉吧~~~前端

  Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。 一句話總結了,node.js就是一個運行環境,我的理解就是釋放了瀏覽器環境對JavaScript的束縛,讓JavaScript能夠作更多的事情。node

  node.js第一篇:HTTP。web

 

HTTP

  超文本傳輸協議(HTTP)是用於傳輸褚如HTML的超媒體文檔的[應用層協議]。它被設計用於Web瀏覽器和Web服務器之間的通訊,但它也能夠用於其餘目的。 json

  HTTP遵循經典的[客戶端-服務端模型],客戶端打開一個鏈接以發送請求,而後等待它收到服務器端響應。api

  HTTP是[無狀態協議],意味着服務器不會在兩個請求直接保留任何數據(狀態)。數組

 

HTTP概述

  

  HTTP是應用層的協議,雖然理論上它能夠經過任何可靠的傳輸協議來發送,可是它仍是
經過[TCP]或者是[TLS]-加密的TCP鏈接來發送。
  它不只被用來傳輸超文本文檔,還用來傳輸圖片、視頻或者向服務器發送如HTML表單這樣的信息。HTTP還能夠根據網頁需求,僅獲取部分Web文檔內容更新網頁。瀏覽器

HTTP組件系統

  HTTP是一個client-server協議:請求經過一個實體(即用戶代理)被髮出。大多數狀況下,這個用戶代理都是指瀏覽器,也多是一個爬區網頁生成維護搜索引擎索引的機器爬蟲等。緩存

  每個發送到服務器的請求,都會被服務器處理並返回一個消息(response)。在client和server之間,還有許多的被稱爲proxies的實體,他們的做用和表現各不相同,好比有些是網關,caches等。

  實際上,在一個瀏覽器和處理請求的服務器之間,還有計算機、路由器、調制解調器等許多實體。因爲Web的層次設計,那些在網絡層和傳輸層的細節都被隱藏起來了。

1、客戶端:user-agent

  user-agent就是任何可以爲用戶發起行爲的工具。但實際上,這個角色一般都是由瀏覽器來扮演。
  要渲染出一個網頁,瀏覽器首先要發送第一個請求來獲取頁面的HTML文檔,再解析文檔中的資源信息發送其餘請求,獲取可執行腳本或css樣式來進行頁面佈局渲染,以及一些其它網頁資源(如圖片和視頻等)。而後,瀏覽器將這些資源整合在一塊兒,展現出一個完整的文檔,也就是網頁。
  一個網頁就是一個超文本文檔,有一部分顯示的文本多是連接,啓動它(一般是鼠標的點擊)就能夠獲取一個新的網頁。網頁使得用戶能夠控制客戶端進行網上衝浪。由瀏覽器來負責發送HTTP請求,呈現HTTP返回消息,讓用戶能清晰地看到返回的網頁內容。

2、Web服務端

  在上述通訊過程的另外一端,是由Web Server來服務並提供客戶端所請求的文檔。Server只是虛擬意義上的:
它能夠是許多共同分擔負載(負載均衡)一組服務器組成的計算機集羣,也能夠是一種複雜的軟件,經過向其餘計算機發起請求來獲取部分或所有資源。
  Server再也不只是一枚單獨的機器,它能夠是在同一個機器上裝載的衆多服務之一。在HTTP/1.1[Host]頭部中,它們甚至能夠共享同一個IP地址。

3、代理(Proxies) 

  在瀏覽器和服務器之間,有許多計算機和其餘設備轉發了HTTP消息。因爲Web棧層次結構的緣由,它們大多都出如今傳輸層、網絡層和物理層上,對於HTTP應用層而言就是透明的,雖然它們可能會對應用層性能有重要影響。還有一部分也表如今應用層上,就是代理(Proxies)。代理既能夠表現得透明,又能夠
不透明(得看請求是否經過它們),代理主要有一下做用:
  1.緩存(能夠是公開的也能夠是私有的,像瀏覽器的緩存)
  2.過濾(像反病毒掃描,家長控制...)
  3.負載均衡(讓多個服務器服務不一樣的請求)
  4.認證(對不一樣資源進行權限管理)
  5.登錄(容許存儲歷史信息)

HTTP基本性質 

  1.HTTP是簡單的 

  2.HTTP是可擴展的

  在HTTP/1.0中出現的[HTTP headers]讓協議擴展變得很是容易。只要服務端和客戶端就新headers達成語義一致,新功能就能夠加入進來。

  3.HTTP是無狀態,有會話的

  HTTP是無狀態的:在同一個鏈接中,兩個執行成功的請求直接是沒有關係的。使用HTTP的頭部擴展,HTTP Cookies就能夠建立有狀態的會話。把Cookies添加到頭部中,建立一個會話讓每次請求都能共享相同的上下文信息,達成相同的狀態。

  4.HTTP 和鏈接

  一個鏈接是由傳輸層來控制的,這基本不屬於HTTP的範圍。HTTP並不須要其下傳輸層的協議是面向鏈接的,只須要它是可靠的,就是說不能丟失消息。
  HTTP/1.0曾爲每個請求/響應都打開一個TCP鏈接,致使了2個缺點:打開一個TCP鏈接須要屢次消息傳遞,速度很慢。但當多個消息週期性發送時,這樣就變得更加高效。
  爲了減小鏈接開銷,HTTP/1.1引入了流水線和持久鏈接的概念:下層的TCP鏈接能夠經過[Connection]頭部來部分控制。HTTP/2則發展得更遠,經過一個鏈接多個消息的方式來讓這個連接始終保持爲暖鏈接。

HTTP 流

  當客戶端想要和服務端進行信息交互時(服務端是指最終服務器,或者是一箇中間代理),過程表現爲:
  1. 打開一個TCP鏈接(或重用以前的一個):TCP鏈接用來發送一條或多條請求,固然也用來接受迴應消息。
客戶端可能重用一個已經存在的鏈接,或者也可能重開幾個新的TCP鏈接連向服務端。
  2. 發送一個HTTP報文(HTTP請求):HTTP報文(在HTTP/2以前)是語義可讀的。在HTTP/2中,這些簡單的消息被封裝在
了幀中,這使得報文不能被直接讀出來,可是報告格式還是相同的。
  客戶端發送一個HTTP請求到服務器的請求消息包括如下格式:請求行、請求頭部、空行和請求數據四個
部分組成。

  3. 讀取服務端返回的報文信息(HTTP響應):狀態行、消息報頭、空行和響應正文。

  content-type:內容類型,通常是指網頁中存在的Content-type,用於定義網絡問卷的類型和網頁的編碼,
決定瀏覽器將以什麼形式、什麼編碼讀取這個文件。
  4. 關閉鏈接或者爲後續請求重用鏈接。
  當HTTP流水線啓動時,後續請求均可以不用等待第一個請求的成功迴應就被髮送。

 

起個Demo

  經過上述的描述,我猜你們也已經瞭解了HTTP是幹什麼的了,說白了就是約定好的一個協議以進行web端和服務器端的正常交互。

  如下會經過起一個HTTP服務進行簡單的增刪改查操做。

  啓動服務:

  經過require HTTP 模塊並建立一個服務器實例createServer,並監聽端口,則在瀏覽器端url輸入localhost:8200便可

  參考api:http://nodejs.cn/api/http.html

const http=require("http");
const server=http.createServer();
server.on("request",(req,res)=>{
    res.end("server had created");
});
server.listen(8200);

  監聽請求和請求方法實現簡單的增刪改查:

  啓動服務後,建立個全局變量users數組存儲用戶,並根據request.method請求方法對請求數據進行增刪改查的處理。

  參考api:http://nodejs.cn/api/url.html

const http=require("http");
const url=require("url");//用於 URL 處理與解析
const server=http.createServer();
server.listen(8200);

let users=[];
server.on("request",(req,res)=>{
    const parseUrl=url.parse(req.url);
    if(parseUrl.path.indexOf('/user')===-1){
        res.statusCode=403;
        res.end(`${res.statusCode} not allowed` );
        return;
    }
    switch(req.method){
        case 'GET':
            if(parseUrl.path.indexOf('/user/')>-1){
                let userName=parseUrl.path.substring(6,parseUrl.path.length);
                let user=users.find(u=>u.name===userName);
                res.statusCode=200;
                res.end(JSON.stringify(users));
            }
            break;
        case 'POST':
            req.on("data",(buffer)=>{
                const userStr=buffer.toString();
                let contentType=req.headers['content-type'];
                if(contentType==='application/json'){
                    let user=JSON.parse(userStr);
                    users.push(user);
                }
                res.statusCode=201;
            });
            req.on("end",()=>{
                res.statusCode=200;
                res.end(JSON.stringify(users));
            });
            break;
        case 'PATCH':
            req.on("data",(buffer)=>{
                let userStr=buffer.toString();
                let contentType=req.headers['content-type'];
                if(contentType==='application/json'){
                    let update=JSON.parse(userStr);
                    let user=users.find(u=>u.name===update.name);
                    console.log(user);
                    user.address=update.address;
                }
                res.statusCode=201;
            });
            req.on("end",()=>{
                res.statusCode=200;
                res.end(JSON.stringify(users));
            });
            break;
        case 'DELETE':
            req.on("data",(buffer)=>{
                let contentType=req.headers['content-type'];
                if(contentType==='application/json'){
                    let index=users.find(u=>u.name===buffer.name);
                    users.splice(index,1);
                }
                res.statusCode=201;
            });
            req.on("end",()=>{
                res.statusCode=200;
                res.end(JSON.stringify(users));
            });
            break;
    }
});

  爲了方便模擬發送請求,咱們能夠下載個postman進行http請求的發送。這樣咱們就完成了簡單的基於HTTP請求的對數據的操做了。

 

書籍推薦

《圖解HTTP》、《HTTP權威指南》

 

 參考

  MDN:https://developer.mozilla.org/zh-CN/docs/Web/HTTP

  菜鳥教程:http://www.runoob.com/http/http-messages.html

 

  Node.js系列第一篇,可能語言組織得沒有這麼好,以爲有哪些須要改進的但願多多提意見,Node.js系列就是開始記錄我入坑node.js的路程的,感興趣的戰友能夠持續關注喔。

相關文章
相關標籤/搜索