国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Node.js系列-http

JinB / 725人閱讀

摘要:是無狀態(tài)協(xié)議,意味著服務(wù)器不會在兩個請求直接保留任何數(shù)據(jù)狀態(tài)。客戶端發(fā)送一個請求到服務(wù)器的請求消息包括以下格式請求行請求頭部空行和請求數(shù)據(jù)四個部分組成。讀取服務(wù)端返回的報文信息響應(yīng)狀態(tài)行消息報頭空行和響應(yīng)正文。

HTTP了解

超文本傳輸協(xié)議(HTTP)是用于傳輸褚如HTML的超媒體文檔的應(yīng)用層協(xié)議。
它被設(shè)計用于Web瀏覽器和Web服務(wù)器之間的通信,但它也可以用于其他目的。
HTTP遵循經(jīng)典的客戶端-服務(wù)端模型,客戶端打開一個連接以發(fā)送請求,然后等待它收到服務(wù)器端響應(yīng)。
HTTP是無狀態(tài)協(xié)議,意味著服務(wù)器不會在兩個請求直接保留任何數(shù)據(jù)(狀態(tài))。

HTTP概述



HTTP是應(yīng)用層的協(xié)議,雖然理論上它可以通過任何可靠的傳輸協(xié)議來發(fā)送,但是它還是
通過TCP或者是TLS-加密的TCP連接來發(fā)送。
它不僅被用來傳輸超文本文檔,還用來傳輸圖片、視頻或者向服務(wù)器發(fā)送如HTML表單這樣的信息。HTTP還可以根據(jù)網(wǎng)頁需求,僅獲取部分Web文檔內(nèi)容更新網(wǎng)頁。

HTTP組件系統(tǒng)

HTTP是一個client-server協(xié)議:請求通過一個實體(即用戶代理)被發(fā)出。大多數(shù)情況下,這個用戶代理都是指瀏覽器,也可能是一個爬區(qū)網(wǎng)頁生成維護搜索引擎索引的機器爬蟲等。
每一個發(fā)送到服務(wù)器的請求,都會被服務(wù)器處理并返回一個消息(response)。在client和server之間,還有許多的被稱為proxies的實體,他們的作用和表現(xiàn)各不相同,比如有些是網(wǎng)關(guān),caches等。

實際上,在一個瀏覽器和處理請求的服務(wù)器之間,還有計算機、路由器、調(diào)制解調(diào)器等許多實體。由于Web的層次設(shè)計,那些在網(wǎng)絡(luò)層和傳輸層的細節(jié)都被隱藏起來了。

客戶端:user-agent

user-agent就是任何能夠為用戶發(fā)起行為的工具。但實際上,這個角色通常都是由瀏覽器來扮演。
要渲染出一個網(wǎng)頁,瀏覽器首先要發(fā)送第一個請求來獲取頁面的HTML文檔,再解析文檔中的資源信息發(fā)送其他請求,獲取可執(zhí)行腳本或css樣式來進行頁面布局渲染,以及一些其它網(wǎng)頁資源(如圖片和視頻等)。然后,瀏覽器將這些資源整合在一起,展示出一個完整的文檔,也就是網(wǎng)頁。
一個網(wǎng)頁就是一個超文本文檔,有一部分顯示的文本可能是鏈接,啟動它(通常是鼠標(biāo)的點擊)就可以獲取一個新的網(wǎng)頁。網(wǎng)頁使得用戶可以控制客戶端進行網(wǎng)上沖浪。由瀏覽器來負責(zé)發(fā)送HTTP請求,呈現(xiàn)HTTP返回消息,讓用戶能清晰地看到返回的網(wǎng)頁內(nèi)容。

Web服務(wù)端

在上述通信過程的另一端,是由Web Server來服務(wù)并提供客戶端所請求的文檔。Server只是虛擬意義上的:
它可以是許多共同分擔(dān)負載(負載均衡)一組服務(wù)器組成的計算機集群,也可以是一種復(fù)雜的軟件,通過向其他計算機發(fā)起請求來獲取部分或全部資源。
Server不再只是一枚多帶帶的機器,它可以是在同一個機器上裝載的眾多服務(wù)之一。在HTTP/1.1Host頭部中,它們甚至可以共享同一個IP地址。

代理(proxies)

在瀏覽器和服務(wù)器之間,有許多計算機和其他設(shè)備轉(zhuǎn)發(fā)了HTTP消息。由于Web棧層次結(jié)構(gòu)的原因,它們大多都出現(xiàn)在傳輸層、網(wǎng)絡(luò)層和物理層上,對于HTTP應(yīng)用層而言就是透明的,雖然它們可能會對應(yīng)用層性能有重要影響。還有一部分也表現(xiàn)在應(yīng)用層上,就是代理(Proxies)。代理既可以表現(xiàn)得透明,又可以
不透明(得看請求是否通過它們),代理主要有一下作用:
1.緩存(可以是公開的也可以是私有的,像瀏覽器的緩存)
2.過濾(像反病毒掃描,家長控制...)
3.負載均衡(讓多個服務(wù)器服務(wù)不同的請求)
4.認(rèn)證(對不同資源進行權(quán)限管理)
5.登陸(允許存儲歷史信息)

HTTP基本性質(zhì)

HTTP是簡單的

HTTP是可擴展的

在HTTP/1.0中出現(xiàn)的HTTP headers讓協(xié)議擴展變得非常容易。只要服務(wù)端和客戶端就新headers達成語義一致,新功能就可以加入進來。

HTTP是無狀態(tài),有會話的

HTTP是無狀態(tài)的:在同一個連接中,兩個執(zhí)行成功的請求直接是沒有關(guān)系的。使用HTTP的頭部擴展,HTTP Cookies就可以創(chuàng)建有狀態(tài)的會話。把Cookies添加到頭部中,創(chuàng)建一個會話讓每次請求都能共享相同的上下文信息,達成相同的狀態(tài)。

HTTP 和連接

一個連接是由傳輸層來控制的,這基本不屬于HTTP的范圍。HTTP并不需要其下傳輸層的協(xié)議是面向連接的,只需要它是可靠的,就是說不能丟失消息。
HTTP/1.0曾為每一個請求/響應(yīng)都打開一個TCP連接,導(dǎo)致了2個缺點:打開一個TCP連接需要多次消息傳遞,速度很慢。但當(dāng)多個消息周期性發(fā)送時,這樣就變得更加高效。
為了減少連接開銷,HTTP/1.1引入了流水線和持久連接的概念:下層的TCP連接可以通過Connection頭部來部分控制。HTTP/2則發(fā)展得更遠,通過一個連接多個消息的方式來讓這個鏈接始終保持為暖連接。

HTTP 流

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

3 讀取服務(wù)端返回的報文信息(HTTP響應(yīng)):狀態(tài)行、消息報頭、空行和響應(yīng)正文。

content-type:內(nèi)容類型,一般是指網(wǎng)頁中存在的Content-type,用于定義網(wǎng)絡(luò)問卷的類型和網(wǎng)頁的編碼,
決定瀏覽器將以什么形式、什么編碼讀取這個文件。
4 關(guān)閉連接或者為后續(xù)請求重用連接。
當(dāng)HTTP流水線啟動時,后續(xù)請求都可以不用等待第一個請求的成功回應(yīng)就被發(fā)送。

起個demo

通過起一個HTTP服務(wù)進行簡單的增刪改查操作。
通過require HTTP 模塊并創(chuàng)建一個服務(wù)器實例createServer,并監(jiān)聽8200端口即可完成監(jiān)聽端口并創(chuàng)建HTTP實例。
參考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);

通過簡單的了解后并啟動HTTP服務(wù)后,我們即可根據(jù)request.method的請求方式對數(shù)據(jù)進行簡單的增刪改查的操作。

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

為了方便模擬發(fā)送請求,我們可以下載個postman進行http請求的發(fā)送。這樣我們就完成了簡單的基于HTTP請求的對數(shù)據(jù)的操作了。

書籍推薦

《圖解HTTP》、《HTTP權(quán)威指南》

參考鏈接

MDN:https://developer.mozilla.org...
菜鳥教程:http://www.runoob.com/http/ht...

備注

文章首發(fā)博客:http://www.cnblogs.com/aaron-...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/92864.html

相關(guān)文章

  • Node.js開發(fā)系列(一)

    摘要:使用和開發(fā)系列之一配置如果你對的安裝不熟悉,請參閱其他教程安裝和。配置如下這里我們使用和兩個依賴包。然后在項目的文件下執(zhí)行,等待執(zhí)行完成。這時候的文件目錄下應(yīng)該包含了這個文件夾。小結(jié)這是一個最簡單的的一個示例,下一節(jié)我們使用來構(gòu)造服務(wù)。 使用node.js,express和pug開發(fā)web系列之一 配置package.json如果你對node的安裝不熟悉,請參閱其他教程安裝node和n...

    Yi_Zhi_Yu 評論0 收藏0
  • Node.js開發(fā)系列(一)

    摘要:使用和開發(fā)系列之一配置如果你對的安裝不熟悉,請參閱其他教程安裝和。配置如下這里我們使用和兩個依賴包。然后在項目的文件下執(zhí)行,等待執(zhí)行完成。這時候的文件目錄下應(yīng)該包含了這個文件夾。小結(jié)這是一個最簡單的的一個示例,下一節(jié)我們使用來構(gòu)造服務(wù)。 使用node.js,express和pug開發(fā)web系列之一 配置package.json如果你對node的安裝不熟悉,請參閱其他教程安裝node和n...

    X_AirDu 評論0 收藏0
  • Node.js 系列:原生 Node.js 應(yīng)用

    摘要:原生應(yīng)用是一個基于引擎的運行環(huán)境使用了一個事件驅(qū)動非阻塞式的模型,使其輕量又高效的包管理器,是全球最大的開源庫生態(tài)系統(tǒng)本文主要介紹構(gòu)建一個應(yīng)用的基本步驟和模塊,并假定你已經(jīng)對有一定的了解本文引用部分代碼作為例子,如果希望參看全部源碼,歡迎去 原生 Node.js 應(yīng)用 Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境Node.js 使用了一個事件驅(qū)...

    Ocean 評論0 收藏0
  • Node.js開發(fā)系列(三)

    摘要:上一節(jié)我們使用代替做了一個簡單的應(yīng)用模塊分離現(xiàn)在我們再次來改造這個最簡單的應(yīng)用。重新啟動在瀏覽器輸入,可以看到顯示。小結(jié)我們成功分離了模塊,使得代碼邏輯更清晰,方便我們下一步繼續(xù)路由控制的功能 上一節(jié)我們使用express代替http做了一個簡單的web應(yīng)用 模塊分離現(xiàn)在我們再次來改造這個最簡單的應(yīng)用。新建一個start.js文件 var http = require(http); v...

    mumumu 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<