Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 91在线视频在线观看,久久91这里精品国产2020,久久精品亚洲精品一区

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          將USB設備使用情況看個清楚

          將USB設備使用情況看個清楚

          在電腦中插入了USB設備并被移除之后,會在系統中留下什么痕跡嗎?如果我們需要了解USB設備在本系統中曾經或正在使用的情況,可以用USBDeview這款小軟件來查明。

          文|如云

          利用USBDeview(下載地址:http://www.nirsoft.net/utils/usbdeview.zip或http://www.nirsoft.net/utils/usbdeview-x64.zip,為32位和64位兩種程序),我們可以列出當前連接到電腦或曾連接過該電腦的所有USB設備。該軟件不用安裝,下載并解包后直接運行EXE程序即可啟動。

          啟動軟件后,窗口中會列出所有在該系統插入或插入過并被記錄下來的USB設備的信息,記錄的項目達40種之多。其中主要項目有:“Device Name”為設備名稱、“Description”為設備描述、“Device Type”為設備類型、“Connected”為是否已連接、“Safe To Unplug”為是否支持安全拔插、“Serial Number”為設備序列號、“Registry Time 1”為設備最近添加時間、“Registry Time 2”為設備上次連接時間、“Firmware Revision”為設備固件版本、“Hub/Port”為連接的Hub和端口編號、“Driver Filename”為設備驅動程序名稱、“Driver InfPath”為設備驅動信息文件路徑。從這些信息中,我們便可以看出是什么樣的設備在什么時間連接了哪個端口,設備型號、驅動程序以及其他具體屬性如何等情況。

          如果需要斷開某個設備的連接,只需在選中該設備條目后點擊工具欄中的紅寶石按鈕,這時“Disabled”一欄將顯示“Yes”;重新連接點擊綠寶石按鈕;點擊藍寶石按鈕則是斷開后再立即自動連接,相當于刷新一下設備的連接。

          當需要卸載列表中的某個設備時,選中該設備并點擊工具欄中的垃圾桶圖標即可;或者也可以通過右鍵菜單選擇“Uninstall Selected Devices”。


          設備的右鍵菜單是一個比較萬能的操作渠道,在其中我們不僅可以完成上述的設備斷開、連接、重新連接等動作,還可以創建設備的桌面快捷方式、打開相關設備、自動播放、打開注冊表相關選項、打開設備INF文件、查看設備屬性等。我們還可以通過右鍵菜單命令測試連接某些設備的讀/寫速度。

          如果需要將選定的設備列表導出為文本/HTML或XML格式,可以選擇“HTML Report - Selected Iterms”菜單命令操作,“HTML Report - All Iterms”為導出所有選項;或者直接點擊工具欄中的磁盤按鈕。導出的格式還可以是TXT、CSV等。

          該程序還支持通過命令行來操作。具體參數的使用以及命令案例,請參閱主程序目錄中的USBDeview.chm幫助文件。


          此外,“Options”菜單中有許多有用的選項,如隱藏啟動、置頂、退縮到任務欄等。CF

          疊樣式表(Cascading Style Sheet,簡稱:CSS)是為網頁添加樣式的代碼。本節將介紹 CSS 的基礎知識,并解答類似問題:怎樣將文本設置為黑色或紅色?怎樣將內容顯示在屏幕的特定位置?怎樣用背景圖片或顏色來裝飾網頁?

          CSS 究竟什么來頭?

          和 HTML 類似,CSS 也不是真正的編程語言,甚至不是標記語言。它是一門樣式表語言,這也就是說人們可以用它來選擇性地為 HTML 元素添加樣式。舉例來說,要選擇一個 HTML 頁面里所有的段落元素,然后將其中的文本改成紅色,可以這樣寫 CSS:

          p {
            color: red;
          }

          不妨試一下:首先新建一個 styles 文件夾,在其中新建一個 style.css 文件,將這三行 CSS 保存在這個新文件中。

          然后再將該 CSS 文件連接至 HTML 文檔,否則 CSS 代碼不會對 HTML 文檔在瀏覽器里的顯示效果有任何影響。(如果你沒有完成前幾節的實踐,請復習處理文件 和 HTML 基礎。在筆記本里有這個方面的內容!)

          1、打開 index.html 文件,然后將下面一行粘貼到文檔頭(也就是 <head></head> 標簽之間)。

          <link href="styles/style.css" rel="stylesheet">

          2、保存 index.html 并用瀏覽器將其打開。應該看到以下頁面:

          如果段落文字變紅,那么祝賀你,你已經成功地邁出了 CSS 學習的第一步。

          “CSS 規則集”詳解

          讓我們來仔細看一看上述CSS:

          整個結構稱為 規則集(通常簡稱“規則”),各部分釋義如下:

          • 選擇器(Selector
          • HTML 元素的名稱位于規則集開始。它選擇了一個或者多個需要添加樣式的元素(在這個例子中就是 p 元素)。要給不同元素添加樣式只需要更改選擇器就行了。
          • 聲明(Declaration
          • 一個單獨的規則,比如說 color: red; 用來指定添加樣式元素的屬性
          • 屬性(Properties
          • 改變 HTML 元素樣式的途徑。(本例中 color 就是 `` 元素的屬性。)CSS 中,由編寫人員決定修改哪個屬性以改變規則。
          • 屬性的值(Property value
          • 在屬性的右邊,冒號后面即屬性的值,它從指定屬性的眾多外觀中選擇一個值(我們除了 red 之外還有很多屬性值可以用于 color )。

          注意其他重要的語法:

          • 每個規則集(除了選擇器的部分)都應該包含在成對的大括號里({})。
          • 在每個聲明里要用冒號(:)將屬性與屬性值分隔開。
          • 在每個規則集里要用分號(;)將各個聲明分隔開。

          如果要同時修改多個屬性,只需要將它們用分號隔開,就像這樣:

          p {
            color: red;
            width: 500px;
            border: 1px solid black;
          }

          多元素選擇

          也可以選擇多種類型的元素并為它們添加一組相同的樣式。將不同的選擇器用逗號分開。例如:

          p, li, h1 {
            color: red;
          }

          不同類型的選擇器

          選擇器有許多不同的類型。上面只介紹了元素選擇器,用來選擇 HTML 文檔中給定的元素。但是選擇的操作可以更加具體。下面是一些常用的選擇器類型:

          選擇器名稱

          選擇的內容

          示例

          元素選擇器(也稱作標簽或類型選擇器)

          所有指定(該)類型的 HTML 元素

          p 選擇 <p>

          ID 選擇器

          具有特定 ID 的元素(單一 HTML 頁面中,每個 ID 只對應一個元素,一個元素只對應一個 ID)

          #my-id 選擇 <p id="my-id"><a id="my-id">

          類選擇器

          具有特定類的元素(單一頁面中,一個類可以有多個實例)

          .my-class 選擇 <p class="my-class"><a class="my-class">

          屬性選擇器

          擁有特定屬性的元素

          img[src] 選擇 <img src="myimage.png"> 而不是 <img>

          偽(Pseudo)類選擇器

          特定狀態下的特定元素(比如鼠標指針懸停)

          a:hover 僅在鼠標指針懸停在鏈接上時選擇 <a>

          選擇器的種類遠不止于此,更多信息請參閱 選擇器。

          字體和文本

          譯注:再一次說明,中文字體文件較大,不適合直接用于 Web Font。

          在探索了一些 CSS 基礎后,我們來把更多規則和信息添加至 style.css 中,從而讓示例更美觀。首先,讓字體和文本變得更漂亮。

          第一步:找到之前Google Font 輸出的地址。并以<link>元素的形式添加進index.html文檔頭(<head></head>之間的任意位置)。代碼如下:

           <link href="https://fonts.font.im/css?family=Open+Sans" rel="stylesheet" type="text/css"> 

          以上代碼為當前網頁下載 Open Sans 字體,從而使自定義 CSS 中可以對 HTML 元素應用這個字體。

          第二步:接下來,刪除 style.css 文件中已有的規則。雖然測試是成功的了,但是紅字看起來并不太舒服。

          第三步:將下列代碼添加到相應的位置,用你在 Google Fonts 找到的字體替代 font-family 中的占位行。( font-family 意味著你想要你的文本使用的字體。)這條規則首先為整個頁面設定了一個全局字體和字號(因為 <html> 是整個頁面的父元素,而且它所有的子元素都會繼承相同的 font-sizefont-family):

          html {
            /* px 表示 “像素(pixels)”: 基礎字號為 10 像素 */
            font-size: 10px;
            /* Google fonts 輸出的 CSS */
            font-family: 'Open Sans', sans-serif;
          }

          注:CSS 文檔中所有位于 /**/ 之間的內容都是 CSS 注釋,它會被瀏覽器在渲染代碼時忽略。你可以在這里寫下對你現在要做的事情有幫助的筆記。

          譯注:/*``*/ 不可嵌套,/*這樣的注釋是/*不行*/的*/。CSS 不接受 // 注釋。

          接下來為文檔體內的元素(<h1> (en-US)、<li><p>)設置字號。將標題居中顯示,并為正文設置行高和字間距,從而提高頁面的可讀性。

             h1 {
               font-size: 60px;
               text-align: center;
             }
             
             p, li {
               font-size: 16px;
               /* line-height 后而可以跟不同的參數,如果是數字,就是當前字體大小乘上數字 */
               line-height: 2;
               letter-spacing: 1px;
             }

          可以隨時調整這些 px 值來獲得滿意的結果,以下是大體效果:

          一切皆盒子

          編寫 CSS 時你會發現,你的工作好像是圍繞著一個一個盒子展開的——設置尺寸、顏色、位置,等等。頁面里大部分 HTML 元素都可以被看作若干層疊的盒子。



          并不意外,CSS 布局主要就是基于盒模型的。每個占據頁面空間的塊都有這樣的屬性:

          • padding:即內邊距,圍繞著內容(比如段落)的空間。
          • border:即邊框,緊接著內邊距的線。
          • margin:即外邊距,圍繞元素外部的空間。



          這里還使用了:

          • width :元素的寬度
          • background-color :元素內容和內邊距底下的顏色
          • color :元素內容(通常是文本)的顏色
          • text-shadow :為元素內的文本設置陰影
          • display :設置元素的顯示模式(暫略)

          開始在頁面中添加更多 CSS 吧!大膽將這些新規則都添加到頁面的底部,而不要糾結改變屬性值會帶來什么結果。

          更改頁面顏色

          html{
            background-color:#00539f;
          }

          這條規則將整個頁面的背景顏色設置為 所計劃的顏色。

          文檔體格式設置

          body{
             width:600px;
             margin:0 auto;
             background-color:#ff9500;
             padding:0 20px 20px 20px;
             border:5px solid black;
          }

          現在是 <body> 元素。以上條聲明,我們來逐條查看:

          • width: 600px; —— 強制頁面永遠保持 600 像素寬。
          • margin: 0 auto; —— 為 marginpadding 等屬性設置兩個值時,第一個值代表元素的上方下方(在這個例子中設置為 0),而第二個值代表左邊右邊(在這里,auto 是一個特殊的值,意思是水平方向上左右對稱)。你也可以使用一個,三個或四個值,參考 這里 。
          • background-color: #FF9500; —— 如前文所述,指定元素的背景顏色。我們給 body 用了一種略微偏紅的橘色以與深藍色的 `` 元素形成反差,你也可以嘗試其它顏色。
          • padding: 0 20px 20px 20px; —— 我們給內邊距設置了四個值來讓內容四周產生一點空間。這一次我們不設置上方的內邊距,設置右邊,下方,左邊的內邊距為20像素。值以上、右、下、左的順序排列。
          • border: 5px solid black; —— 直接為 body 設置 5 像素的黑色實線邊框。

          定位頁面主標題并添加樣式

          h1{
            margin: 0;
            padding:20px 0;
            color: #00539f;
            text-shadow:3px 3px 1px black
          }

          你可能發現頁面的頂部有一個難看的間隙,那是因為瀏覽器會在沒有任何 CSS 的情況下 給 <h1>en-US等元素設置一些默認樣式。但這并不是個好主意,因為我們希望一個沒有任何樣式的網頁也有基本的可讀性。為了去掉那個間隙,我們通過設置margin: 0;來覆蓋默認樣式。

          至此,我們已經把標題的上下內邊距設置為 20 像素,并且將標題文本與 HTML 的背景顏色設為一致。

          需要注意的是,這里使用了一個 text-shadow 屬性,它可以為元素中的文本提供陰影。四個值含義如下:

          • 第一個值設置水平偏移值 —— 即陰影右移的像素數(負值左移)。
          • 第二個值設置垂直偏移值 —— 即陰影下移的像素數(負值上移)。
          • 第三個值設置陰影的模糊半徑 —— 值越大產生的陰影越模糊。
          • 第四個值設置陰影的基色。

          不妨嘗試不同的值看看能得出什么結果。

          圖像居中

          img{
            display:block;
            margin:0 auto;
          }

          最后,我們把圖像居中來使頁面更美觀。可以復用 body 的margin: 0 auto,但是需要一點點調整。<body>元素是塊級元素,意味著它占據了頁面的空間并且能夠賦予外邊距和其他改變間距的值。而圖片是內聯元素,不具備塊級元素的一些功能。所以為了使圖像有外邊距,我們必須使用display: block 給予其塊級行為。

          注:以上說明假定所選圖片小于頁面寬度(600 pixels)。更大的圖片會溢出 body 并占據頁面的其他位置。要解決這個問題,可以:

          1)使用 圖片編輯器 來減小圖片寬度; 2)用 CSS 限制圖片大小,即減小 <img> 元素 width 屬性的值(比如 400 px)。

          注:如果你暫時不能理解 display: block 和塊級元素與行內元素的差別也沒關系;隨著你對 CSS 學習的深入,你將明白這個問題。

          小結

          如果你按部就班完成本文的實踐,那么最終可以得到以下頁面


          相關推薦:

          前端新手看過來,手把手帶你輕松上手html的實操

          我們向瀏覽器的地址欄輸入URL的時候,網絡會進行一系列的操作,最終獲取到我們所需要的文件,如何交給瀏覽器進行渲染

          我們所關注的問題也就是:

          • 如何獲取到我們所需要的文件
          • 瀏覽器是如何渲染的

          大致的執行順序

          • URL解析
          • DNS 解析:緩存判斷 + 查詢IP地址
          • TCP 連接:TCP 三次握手
          • SSL/TLS四次握手(只有https才有這一步)
          • 瀏覽器發送請求
          • 服務器響應請求并返回數據
          • 瀏覽器解析渲染頁面
          • 斷開連接:TCP 四次揮手

          URL解析

          瀏覽器先會判斷輸入的字符是不是一個合法的URL結構,如果不是,瀏覽器會使用搜索引擎對這個字符串進行搜索

          URL結構組成

          https://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#anchor

          • 協議:https:// 互聯網支持多種協議,必須指明網址使用哪一種協議,默認是 HTTP 協議。 也就是說,如果省略協議,直接在瀏覽器地址欄輸入www.example.com,那么瀏覽器默認會訪問http://www.example.com。 HTTPS 是 HTTP 的加密版本,出于安全考慮,越來越多的網站使用這個協議。
          • 主機:www.example.com 主機(host)是資源所在的網站名或服務器的名字,又稱為域名。上例的主機是www.example.com。 有些主機沒有域名,只有 IP 地址,比如192.168.2.15。
          • 端口:https:// 同一個域名下面可能同時包含多個網站,它們之間通過端口(port)區分。 “端口”就是一個整數,可以簡單理解成,訪問者告訴服務器,想要訪問哪一個網站。 默認端口是80,如果省略了這個參數,服務器就會返回80端口的網站。 端口緊跟在域名后面,兩者之間使用冒號分隔,比如www.example.com:80。
          • 路徑:/path/to/myfile.html 路徑(path)是資源在網站的位置。比如,/path/index.html這個路徑,指向網站的/path子目錄下面的網頁文件index.html 互聯網的早期,路徑是真實存在的物理位置。現在由于服務器可以模擬這些位置,所以路徑只是虛擬位置 路徑可能只包含目錄,不包含文件名,比如/foo/,甚至結尾的斜杠都可以省略 這時,服務器通常會默認跳轉到該目錄里面的index.html文件(即等同于請求/foo/index.html),但也可能有其他的處理(比如列出目錄里面的所有文件),這取決于服務器的設置 一般來說,訪問www.example.com這個網址,很可能返回的是網頁文件www.example.com/index.html
          • 查詢參數:?key1=value1&key2=value2 查詢參數(parameter)是提供給服務器的額外信息。參數的位置是在路徑后面,兩者之間使用?分隔 查詢參數可以有一組或多組。每組參數都是鍵值對(key-value pair)的形式,同時具有鍵名(key)和鍵值(value),它們之間使用等號(=)連接。比如,key1=value就是一個鍵值對,key1是鍵名,value1是鍵值 多組參數之間使用&連接,比如key1=value1&key2=value2
          • 錨點:#anchor 錨點(anchor)是網頁內部的定位點,使用#加上錨點名稱,放在網址的最后,比如#anchor 瀏覽器加載頁面以后,會自動滾動到錨點所在的位置 錨點名稱通過網頁元素的id屬性命名

          DNS解析

          DNS(Domain Names System),域名系統,是互聯網一項服務,是進行域名和與之相對應的 IP 地址進行轉換的服務器

          第一步:緩存判斷

          判斷是正確的URL格式之后,DNS會在我們的緩存中查詢是否有當前域名的IP地址

          基本步驟:

          • 瀏覽器緩存:瀏覽器檢查是否在緩存中
          • 操作系統緩存:操作系統DNS緩存,去本地的hosts文件查找
          • 路由器緩存:路由器DNS緩存
          • ISP 緩存: ISP DNS緩存(ISP DNS 就是在客戶端電腦上設置的首選 DNS 服務器,又稱本地的DNS服務器)

          在經歷上述緩存查找還沒有找到的話,就進行下一步查詢操作

          第二步:查詢IP地址

          瀏覽器會去根域名服務器中查找,如果還沒有就去頂級域名服務器中查找,最后是權威域名服務器。

          找到IP地址后,將它記錄在緩存中,供下次使用。

          TCP連接:三次握手

          簡單理解

          簡單的理解就是:

          客戶端:hello,你好,你是server嗎?
          服務端:hello,你好,我是server,你是client嗎
          客戶端:yes,我是client
          開始數據傳輸.....
          ——————————————————————————————————————————
          客戶端(男人):我喜歡你,咱倆處對象吧
          服務端(女人):我也喜歡你,我答應你
          客戶端(男人):太棒了,我們現在去看電影吧
          開始數據傳輸.....
          


          然后雙方就正確建立連接,開始傳輸數據

          詳細分析

          • 第一次握手:客戶端發送一個帶 SYN=1,Seq=x 的數據包到服務器端口 第一次握手,由瀏覽器發起,告訴服務器我要發送請求了 SYN(synchronous):請求建立連接 seq(sequence):隨機序列號 請注意TCP規定SYN被設置為1的報文段不能攜帶數據但要消耗掉一個序號。
          • 第二次握手:服務器發回一個帶 SYN=1, ACK=1, seq=y, ack=x+1 的響應包以示傳達確認信息 第二次握手,由服務器發起,告訴客戶端我準備接受了,你趕緊發送吧 ACK(acknowledgement):確認,是一個確定字符 ack:ack=上一次的seq+1,作用是接受上一次遠端主機傳來的seq,加一然后再傳給客戶端,提示客戶端已經成功接收上一次所有數據 請注意這個報文段不能攜帶數據,因為它是SYN被設置為一的報文段但同樣要消耗掉一個序號
          • 第三次握手:客戶端再回傳一個帶 ACK,seq=x + 1, ack=y + 1 的數據包,代表“握手結束” 第三次握手,由瀏覽器發送,告訴服務器,我馬上就發了,準備接受吧 確認報文段可以攜帶數據。但如果不攜帶數據則不消耗序號,在這種情況下所發送的下一個數據報文段的序號仍是x + 1

          然后雙方就正確建立連接,開始傳輸數據

          SSL/TLS四次握手

          HTTPS 建立連接的過程,先進行 TCP 三次握手,再進行 TLS 四次握手(僅對https)

          因為 HTTPS 都是基于 TCP 傳輸協議實現的,得先建立完可靠的 TCP 連接才能做 TLS 握手的事情。

          第一次握手:客戶端發出請求Client Hello

          • 首先,客戶端先向服務器發出加密通信的請求,這被叫做clienthello請求。
          • 在這一步,客戶端主要向服務器提供以下信息:
            • 支持的協議版本,比如TLS1.0版本
            • 支持的加密方法,比如RSA公鑰加密
            • 一個客戶端生成的隨機數(client random), 稍后用于生成對話密鑰(session key)

          第二次握手:服務器回應Server Hello

          • 服務器收到客戶端請求后,向客戶端發出回應,這叫做serverhello
          • 這一步服務器主要干三件事:
            • 確認使用的加密通信協議版本,比如TLS1.00版本。如果游覽器與服務器支持的版本不一致,服務器關閉加密通信
            • 確認使用的加密方法(客戶端所支持),比如RSA公鑰加密
            • 將服務器證書、非對稱加密的公鑰,以及一個隨機數(Server random)發送給客戶端游覽器

          客戶端驗證證書

          客戶端收到服務器回應以后,首先驗證服務器證書,驗證手段就是執行如下三種檢查:

          • 檢查證書是否已過期;
          • 檢查證書中的域名與實際域名是否一致
          • 檢查證書是否是可信機構頒布的

          如果,上述過程中有任何一個環節發現問題,那么瀏覽器就會向訪問者顯示一個警告,由其選擇是否還要繼續通信。如果證書受信任,或者是用戶接受了不受信的證書,瀏覽器會生成一串新的隨機數(Premaster secret )

          第三次握手:客戶端回應

          此時,瀏覽器會根據前三次握手中的三個隨機數:

          • Client random
          • Server random
          • Premaster secret

          通過一定的算法來生成 “會話密鑰” (Session Key),這個會話密鑰就是接下來雙方進行對稱加密解密使用的密鑰!

          第四次握手:服務端回應

          服務端收到客戶端的回復,利用已知的加密解密方式進行解密,服務器收到客戶端的第三個隨機數( Premaster secret) 之后,使用同樣的算法計算出 “會話密鑰” (Session Key)。

          至此,整個握手階段全部結束。接下來,客戶端與服務器進入加密通信,就完全是使用普通的 HTTP 協議,只不過用 “會話密鑰” 加密內容。(非對稱加密解密將不再使用,接下來完全由對稱加密接手了,因為密鑰已經安全的傳送給了通信的雙方)

          總結

          1. 客戶端請求建立SSL鏈接,并向服務發送一個隨機數–Client random客戶端支持的加密方法,比如RSA公鑰加密,此時是明文傳輸
          2. 服務端回復一種客戶端支持的加密方法一個隨機數–Server random、授信的服務器證書非對稱加密的公鑰
          3. 客戶端收到服務端的回復后利用服務端的公鑰,加上新的隨機數–Premaster secret 通過服務端下發的公鑰及加密方法進行加密,發送給服務器
          4. 服務端收到客戶端的回復,利用已知的加解密方式進行解密,同時利用Client random、Server random和Premaster secret通過一定的算法生成HTTP鏈接數據傳輸的對稱加密key – session key

          瀏覽器發送請求

          連接建立成功之后,瀏覽器向服務器發送HTTP請求報文,來獲取自己想要的數據

          請求報文由請求行、請求頭、空行、請求體四部分組成

          • 請求行:有請求方法、請求的url、http協議及其版本
          • 請求頭:把瀏覽器的一些基礎信息告訴服務器。比如包含了瀏覽器所使用的操作系統、瀏覽器內核等信息,以及當前請求的域名信息、瀏覽器端的 Cookie 信息等
          • 空行:最后一個請求頭之后是一個空行,發送回車符和換行符,通知服務器以下不再有請求頭
          • 請求體(報文主體/請求中文):當使用POST, PUT等方法時,通常需要客戶端向服務器傳遞數據。這些數據就儲存在請求正文中。在請求包頭中有一些與請求正文相關的信息,例如: 現在的Web應用通常采用Rest架構,請求的數據格式一般為json。這時就需要設置Content-Type: application/json。

          服務端響應請求并返回數據

          服務器對http請求報文進行解析,并給客戶端發送HTTP響應報文對其進行響應

          HTTP響應報文也是由狀態行、響應頭、空行、響應體四部分組成

          • 響應行/狀態行:由 HTTP 版本協議字段、狀態碼和狀態碼的描述文本 3 個部分組成
          • 響應頭:用于指示客戶端如何處理響應體,告訴瀏覽器響應的類型、字符編碼和字節大小等信息
          • 空行:最后一個響應頭部之后是一個空行,發送回車符和換行符,通知服務器以下不再有響應頭部。
          • 響應體:返回客戶端所需數據

          這個時候瀏覽器拿到我們服務器返回的HTML文件,可以開始解析渲染頁面

          瀏覽器解析渲染頁面

          當我們經歷了上述的一系列步驟之后,我們的瀏覽器就拿到了我的HTML文件那么它又是如何解析整個頁面并且最終呈現出我們的網頁呢?

          渲染流程圖

          簡圖:從這張圖上我們可以得出一個重要的結論:下載CSS文件并不會阻塞HTML的解析

          詳圖

          詳細解析步驟

          解析一:HTML解析過程

          默認情況下服務器會給瀏覽器返回index.html文件,所以解析HTML是所有步驟的開始:解析HTML,會 構建DOM Tree

          當遇到我們的script文件的時候,我們是不能進行去構建DOM Tree的。它會停止繼續構建,首先下載JavaScript代碼,并且執行JavaScript的腳本,只有等到JavaScript腳本執行結束后,才會繼續解析HTML,構建DOM樹

          具體的相關細節看下面的script與頁面解析

          解析二:生成CSS規則

          • 在解析的過程中,如果遇到CSS的link元素,那么會由瀏覽器負責下載對應的CSS文件
            • 注意:下載CSS文件是不會影響DOM的解析的
          • 瀏覽器下載完CSS文件后,就會對CSS文件進行解析,解析出對應的規則樹
            • 我們可以稱之為 CSSOM (CSS Object Model,CSS對象模型

          解析三:構建Render Tree

          當有了 DOM Tree 和 CSSOM Tree 后,就可以兩個結合來 構建 Render Tree

          • 注意一:link元素不會阻塞DOM Tree的構建過程,但是會阻塞Render Tree的構建過程
            • 因為Render Tree在構建時,需要對應的CSSOM Tree。當我們DOMTree解析完成的時候,如果CSSOM Tree沒解析完成就會阻塞。當然一般情況下瀏覽器會進行優化處理,不會傻傻的等待
          • 注意二:Render Tree和DOMTree并不是一一對應的關系
            • 比如對于display為none的元素,壓根不會出現在render tree中

          解析四:布局(layout)和繪制(Paint)

          • 第四步是在**渲染樹(Render Tree)**上運行 布局(Layout) 以計算每個節點的幾何體。 渲染樹會 表示 要顯示哪些節點以及其他樣式,但是 不表示 每個節點的尺寸、位置 等信息 布局的主要目的是為了確定呈現樹中所有節點的寬度、高度和位置信息
          • 第五步是將每個節點 繪制(Paint) 到屏幕上 在繪制階段,瀏覽器將布局階段計算的 每個frame轉為屏幕上實際的像素點 包括 將元素的可見部分進行繪制,比如文本、顏色、邊框、陰影、替換元素(比如img)

          特殊解析:composite合成

          • 繪制的過程,可以將布局后的元素繪制到多個合成圖層中【這是瀏覽器的一種優化手段】
          • 默認情況下,標準流中的內容都是被繪制在同一個圖層(Layer)中的
          • 而一些特殊的屬性,會創建一個新的合成層(Compositinglayer ),并且新的圖層可以利用GPU來加速繪制
            • 因為每個合成層都是單獨渲染的
          • 那么哪些屬性可以形成新的合成層呢?常見的一些屬性:
            • 3D transforms
            • video、canvas、iframe
            • opacity動畫轉換時
            • position: fixed
            • will-change:一個實驗性的屬性,提前告訴瀏覽器元素可能發生哪些變化
            • animation或 transition設置了opacity、transform
          • 分層確實可以提高性能,但是它以內存管理為代價,因此不應作為web性能優化策略的一部分過度使用

          其他相關概念

          回流

          • 回流reflow(也可以稱之為重排) 第一次確定節點的大小和位置,稱之為布局(layout) 之后對節點的大小、位置修改 重新計算 稱之為回流
          • 什么情況下引起回流呢? 比如DOM結構發生改變(添加新的節點或者移除節點) 比如改變了布局(修改了width、height、padding、font-size等值) 比如窗口resize(修改了窗口的尺寸等) 比如調用getComputedStyle方法獲取尺寸、位置信息

          重繪

          • 重繪repaint【字面理解就是對頁面再做繪制】 第一次渲染內容稱之為繪制(paint) 之后重新渲染稱之為重繪
          • 什么情況下會引起重繪呢? 比如修改背景色、文字顏色、邊框顏色、樣式等

          聯系

          • 回流一定會引起重繪,所以回流是一件很消耗性能的事情。
          • 所以在開發中要盡量避免發生回流 修改樣式時盡量一次性修改【比如通過cssText修改,比如通過添加class修改】 盡量 避免頻繁的操作DOM【我們可以在一個DocumentFragment或者父元素中將要操作的DOM操作完成,再一次性的操作】 盡量 避免通過getComputedStyle獲取尺寸、位置等信息 對某些元素使用position的absolute或者fixed【并不是不會引起回流,而是開銷相對較小,不會對其他元素造成影響】

          script元素

          script元素和頁面聯系

          • 我們現在已經知道了頁面的渲染過程,但是JavaScript在哪里呢? 事實上,瀏覽器在解析HTML的過程中,遇到了 script元素是不能繼續構建DOM樹的 它會 停止繼續構建,首先下載JavaScript代碼,并且執行JavaScript的腳本 只有 等到JavaScript腳本執行結束后,才會繼續解析HTML,構建DOM樹
          • 為什么要這樣做呢? 這是 因為JavaScript的作用之一就是操作DOM,并且可以修改DOM 如果我們等到DOM樹構建完成并且渲染再執行JavaScript會造成嚴重的回流和重繪,影響頁面的性能 所以會在遇到script元素時,優先下載和執行JavaScript代碼,再繼續構建DOM樹
          • 但是這個也往往會帶來新的問題,特別是現代頁面開發中: 在目前的開發模式中(比如Vue、React),腳本往往比HTML頁面更“重”,處理時間需要更長 所以會造成頁面的解析阻塞,在腳本下載、執行完成之前,用戶在界面上什么都看不到
          • 為了解決這個問題,script元素給我們提供了兩個屬性(attribute) : defer和async

          defer屬性

          • defer屬性告訴瀏覽器 不要等待腳本下載,而繼續解析HTML,構建DOM Tree
            • 腳本會 由瀏覽器來進行下載,但是不會阻塞DOM Tree的構建過程
            • 如果腳本提前下載好了,它會 等待DOM Tree構建完成,在DOMContentLoaded事件之前先執行defer中的代碼
          • 所以DOMContentLoaded總是會等待defer中的代碼先執行完成
          <script src="./foo.js" defer></script>
          <script>
          	 window.addEventListener("DOMContentLoaded",()=>{
                   console.log("DOMContentLoaded");
               })
          </script>
          • 多個帶defer的腳步是可以保持正確的執行順序的
          • 從某種角度來說,defer可以提高頁面的性能,并且推薦放到head元素中
          • 注意:defer僅適用于外部腳本,對于script默認內容會被忽略

          async屬性

          • async特性與defer有些類似,它也能夠讓腳本不阻塞頁面
          • async是讓一個腳本完全獨立的:
            • 瀏覽器 不會因async 腳本而阻塞(與defer類似)
            • async腳本不能保證順序,它是獨立下載、獨立運行,不會等待其他腳本
            • async不會能保證在DOMContentLoaded之前或者之后執行
          • defer通常用于需要在文檔解析后操作DOM的JavaScript代碼,并且對多個script文件有順序要求的
          • async通常用于獨立的腳本,對其他腳本,甚至DOM沒有依賴的

          斷開連接:TCP 四次揮手

          在渲染完成后,瀏覽器可能會繼續加載頁面中的其他資源,如異步加載的內容或者通過JavaScript生成的動態內容。

          而在此過程中,如果沒有其他資源需要加載,瀏覽器將與服務器之間的TCP連接斷開。

          簡單理解

          復制代碼主動方:我已經關閉了向你那邊的主動通道了,這是我最后一次給你發消息了,之后只能被動接收你的信息了
          被動方:收到你通道關閉的信息
          被動方:那我也告訴你,我這邊向你的主動通道也關閉了
          主動方:最后收到你關閉的信息,OK結束
          斷開連接,結束通訊
          ————————————————————————————————————————————————————————————————————————————
          提出分手的可能是男生(客戶端),也可能是女生(服務端)
          主動方:分手吧,我不喜歡你了!
          被動方:行,你等我忙完手上的工作我在收拾你!
          被動方:我忙完了,分手就分手!
          主動方:好,好聚好散,拜拜!
          斷開連接,結束通訊
          

          詳細分析

          由于TCP連接是全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務后,發送一個FIN來終止這一方向的連接,收到一個FIN只是意味著這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉。

          任何一方都可以在數據傳送結束后發出連接釋放的通知,所有主動發起關閉請求可以是客戶端,也可以是服務端

          這里我們假設是由客戶端先主動發起關閉請求

          • 第一次揮手:TCP客戶進程會發送TCP連接釋放報文段,并進入終止等待1(FIN-WAIT-1)狀態。 FIN:終止位,表示斷開TCP連接 TCP規定終止位FIN等于1的報文段即使不攜帶數據,也要消耗掉一個序號
          • 第二次揮手:TCP服務器進程收到TCP連接釋放報文段后,會發送一個普通的TCP確認報文段并進入關閉等待(CLOSE-WAIT)狀態。 序號seq字段的值設置為v,與之前收到的TCP連接釋放報文段中的確認號匹配 TCP客戶進程收到TCP確認報文段后就進入終止等待2(FIN-WAIT-2)狀態,等待TCP服務器進程發出的TCP連接釋放報文段 這時的TCP連接屬于半關閉狀態,也就是TCP客戶進程已經沒有數據要發送了。但如果TCP服務器進程還有數據要發送,TCP客戶進程仍要接收,也就是說從TCP服務器進程到TCP客戶進程這個方向的連接并未關閉,這個狀態可能要持續一段時間。
          • 第三次揮手:TCP服務器進程發送TCP連接釋放報文段 假定序號seq字段的值為w,這是因為在半關閉狀態下,TCP服務器進程可能又發送了一些數據。 確認號ack字段的值為u+1,這是對之前收到的TCP連接釋放報文段的重復確認。
          • 第四次揮手:TCP服務器進程收到確定報文段后就進入關閉狀態,而TCP客戶進程還要經過2MSL后才能進入關閉狀態。

          之后斷開連接,結束通訊

          總結

          • 瀏覽器先判斷是否為合法的url格式,不合法則在搜索引擎中搜索
          • 合法后,DNS解析會先判斷緩存中是否有url的ip地址。
          • 緩存的查詢順序是:瀏覽器緩存 -> 操作系統緩存(本地的hosts文件) -> 路由器緩存 -> 本地的DNS服務器緩存
          • 在緩存中沒有的情況,則向服務器發起請求查詢ip地址。
          • 查詢IP地址的順序是:根域名服務器 -> 頂級域名服務器 -> 權威域名服務器。直到查找到返回,并將其存儲在緩存中下次使用
          • TSP建立連接,也就是三次握手
          • 第一次握手,攜帶建立連接請求SYN=1和隨機序列seq=x
          • 第二次握手,攜帶確定字段ACK=1、連接請求SYN=1、隨機序列seq=y和ack為上一次握手的seq+1,就是x+1
          • 第三次握手,攜帶確定字段ACK=1、ack=y+1、seq=x+1
          • 如果是https,還有一個TLS四次握手
          • 第一次握手,客戶端向服務端發送 支持的協議版本 + 支持的加密方法 + 生成的隨機數
          • 第二次握手,服務端向客戶端發送 證書 + 公鑰 + 隨機數
          • 第三次握手前,客戶端會先驗證證書有沒有過期、域名對不對、是否可信機構頒發的。
          • 沒有問題或者用戶接受不受信的證書,瀏覽器會生成一個新的隨機數
          • 第三次握手,將之前的三個隨機數通過一定的算法生成會話秘鑰,之后的加密解密都是用這個秘鑰
          • 第四次握手,服務端收到回復,是用確定的加密方法進行解密,得到第三個隨機數,使用同樣的算法計算出會話秘鑰
          • 建立連接之后,瀏覽器發送http請求
          • 請求報文由請求行、請求頭、空行和請求體組成
          • 服務器解析請求報文,返回響應報文
          • 響應報文由響應行、響應頭、空行和響應體組成,我們需要的html文件就在響應體中
          • 瀏覽器拿到html文件并開始解析,構建dom tree。遇到css文件,下載并構建CSSOM tree。等到兩者都構建完成之后,一起構建Render tree。然后進行布局和繪制
          • 其中遇到了script標簽,則停止構建dom tree,等下載完成之后才會繼續構建dom tree
          • 當資源傳輸完畢之后,TSP關閉連接,進行四次揮手的操作,其中四次揮手的操作客戶端和服務器都可以發起
          • 第一次揮手,攜帶斷開連接的FIN=1、確定字段ACK=1、隨機序列seq=u,ack=v
          • 第二次揮手,攜帶確定字段ACK=1、隨機序列seq=v,ack=u+1
          • 第三次揮手,攜帶確定字段ACK=1、斷開連接FIN=1、隨機序列seq=w、ack=u+1
          • 第四次揮手,攜帶確定字段ACK=1,隨機序列seq=u+1,ack=w+1
          • 等待2MSL后進入關閉狀態
          • 斷開連接,結束通訊


          作者:前端實習生鯨落
          鏈接:https://juejin.cn/post/7279093851000242234


          主站蜘蛛池模板: 中文字幕一区二区区免| 亚洲国产成人久久综合一区77| 波霸影院一区二区| 丰满人妻一区二区三区视频53| 亚洲综合在线成人一区| 国产另类ts人妖一区二区三区| 在线一区二区三区| 射精专区一区二区朝鲜| 国产一区二区视频在线观看| 中字幕一区二区三区乱码| 亚洲不卡av不卡一区二区| 精品一区二区三区色花堂| 亚洲一区二区三区深夜天堂| 国产免费无码一区二区| 国产一区二区三区无码免费| 蜜桃传媒一区二区亚洲AV| 国产高清在线精品一区| 国产午夜精品一区理论片飘花| 久久精品无码一区二区app| 精品一区二区三区AV天堂| 国产日韩视频一区| 狠狠综合久久av一区二区| 日韩一区二区a片免费观看| 一本一道波多野结衣AV一区| 99精品国产高清一区二区麻豆 | 国产裸体歌舞一区二区| 久久久精品日本一区二区三区| 精品人妻一区二区三区四区| 天天看高清无码一区二区三区| 成人精品一区二区三区电影| 成人毛片无码一区二区| 国产成人一区二区三区免费视频| 亚洲av成人一区二区三区在线播放| 国产精品综合AV一区二区国产馆| 91国偷自产一区二区三区| 97人妻无码一区二区精品免费| 在线电影一区二区三区| 一区二区三区日本视频| 亚洲一区爱区精品无码| 在线视频一区二区| 精品国产一区二区三区香蕉事|