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 中文字幕欧美在线观看,免费一区二区三区,日韩去日本高清在线

          整合營銷服務商

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

          免費咨詢熱線:

          詳解網絡請求Axios

          xios是什么?

          Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。我們知道 Promise 是 js 異步的一種解決方案,它最大的特性就是可以通過 .then 的方式來進行鏈式調用。

          其實說白了axios是對ajax的封裝,axios有的ajax都有,ajax有的axios不一定有,總結一句話就是axios是ajax,ajax不止axios。

          為什么選擇axios?

          1. vue的作者尤雨溪推薦使用axios.
          2. 符合前后端分離的趨勢,及前端的MVVM的浪潮

          功能特點:

        1. 在瀏覽器中發送XMLHttpRequests請求
        2. 在node.js中發送http請求
        3. 支持Promise API
        4. 攔截請求和響應
        5. 轉換請求和響應數據
        6. 取消請求
        7. 自動轉換 JSON 數據
        8. 客戶端支持防御 XSRF
        9. 支持多種請求方式:

        10. axios(config)
        11. axios.request(config)
        12. axios.get(url, [, config])
        13. axios.delete(url, [, config])
        14. axios.head(url, [, config])
        15. axios.post(url, [,data[,config] ])
        16. axios.put(url, [,data[,config] ])
        17. axios.patch(url, [,data[,config] ])
        18. Axios的基本使用

          axios的使用比較簡單,文檔講得也非常清晰,你應該先閱讀axios的官方文檔:axios文檔。

          在html頁面中直接引入使用:

          <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

          Html頁面基本使用

          以下案例中的get請求地址為crmeb相關演示站地址,可用于測試獲取!

          1. 獲取一個get請求
          <script>
            const url = 'https://store.crmeb.net/api/pc/get_category_product'
            axios({
              url: url,
              method: 'get',  // 這里可以省略,默認為get
            }).then(res => {
              // 返回請求到的數據
              console.log(res)
            }).catch(err => {
              // 返回錯誤信息
              console.log(err)
            })  
          </script>
          1. 在get請求的url中傳參,只需要定義一個params:{}即可!
          <script>
            const url = 'https://store.crmeb.net/api/pc/get_category_product'
            axios({
              url: url,
              method: 'get',  // 這里可以省略,默認為get
              // 這里的鍵值對會拼接成這樣url?page=1&limit=3
              params: {
                page: 1,
                limit: 3
              }
            }).then(res => {
              // 返回請求到的數據
              console.log(res)
            }).catch(err => {
              // 返回錯誤信息
              console.log(err)
            })  
          </script>
          1. 發送一個post請求,與get請求類似,只需要將method改為post,定義一個data:{}即可,data中的數據則是服務器需要接收的字段數據!
          <script>
          axios({
            method: 'post',
            url: '/user/12345',
            data: {
              firstName: 'Fred',
              lastName: 'Flintstone'
            }
          }).then(res => {
              // 返回請求到的數據
              console.log(res)
            }).catch(err => {
              // 返回錯誤信息
              console.log(err)
            });
          </script>
          1. 發送一個并發請求

          如果在開發中需要等到多個接口的數據同時請求到后才能繼續后邊的邏輯,那么即可使用并發請求,axios并發請求,使用all方法,all方法的參數為一個數組,數組的每個值可以為一次請求,請求完成后直接.then即可合并兩次請求的數據,返回結果為一個數組!

          <script>
          axios.all([
              axios({
                  url: 'https://store.crmeb.net/api/pc/get_products',
                  params: {
                      page: 1,
                      limit: 20,
                      cid: 57,
                      sid: 0,
                      priceOrder: '', 
                      news: 0,
                  }
              }),
              axios({
                  url: 'https://store.crmeb.net/api/pc/get_company_info',
              })
          ]).then(results => {
              console.log(results)
          })
          </script>

          如果你想自動把這個數組展開的話在then()方法中傳入axios.spread()方法即可,如下所示:

          <script>
          axios.all([
              axios({
                  url: 'https://store.crmeb.net/api/pc/get_products',
                  params: {
                      page: 1,
                      limit: 20,
                      cid: 57,
                      sid: 0,
                      priceOrder: '', 
                      news: 0,
                  }
              }),
              axios({
                  url: 'https://store.crmeb.net/api/pc/get_company_info',
              })
          ]).then(axios.spread((res1, res2) => {
              console.log(res1);
              console.log(res2);
          }))
          </script>

          但在使用vue組件化開發的時候一般我們會通過npm安裝,引入項目!

          組件化開發中使用

          1. 使用npm進行安裝
          npm install axios --save

          一般在實際項目中我們并不會像上邊這樣直接去使用axios請求數據,而是將axios封裝在一個單獨的文件,這樣做的目的主要是用來抽取公共邏輯到一個配置文件里,對這些公共邏輯做一個封裝,即使某一天這個axios框架不維護了,或者出現了重大bug也不再修復的時候,我們可以只修改配置文件即可達到全局修改的目的,如果把每次請求邏輯都寫到對應的組件中,那修改起來簡直就是一個噩夢!

          1. 封裝一個axios的請求文件request.js

          在項目的src目錄下創建一個network文件夾,再在其中創建一個request.js文件,路徑為:src/network/request.js

          // src/network/request.js
          
          // 引入axios
          import axios from 'axios'
          
          // 這里未使用default導出,是為了以后的擴展,便于導出多個方法
          export function request(config){
              // 創建axios實例
              const instance = axios.create({
                  // 這里定義每次請求的公共數據,例如全局請求頭,api根地址,過期時間等
                  // 具體參數可參考axios的官方文檔
                  baseURL: 'http://demo26.crmeb.net/api',
                  timeout: 5000
              })
              
              // 攔截請求,如果獲取某個請求需要攜帶一些額外數據
              instance.interceptors.request.use(
                  config => {
                      console.log(config);
                      return config;
                  }, err => {
                      console.log(err);
                  })
                  
              // 攔截響應
              instance.interceptors.response.use(
                  res => {
                      console.log(res)
                      return res.data
                  }, err => {
                      console.log(err)
                  }
              )
              
              // 發送請求
              return instance(config)  
          1. 使用我們封裝的request請求

          一般我們會將所有的請求放在一個api.js文件中,將每次請求封裝為一個方法,比如我這里會在request.js的同目錄創建一個api.js文件封裝我們所有的請求。

          import { request } from '../api/request'
          
          // 獲取分類
          export const getHomeCategory = () => {
              return request({
                  url: '/category'
              })
          }
          
          // 獲取banner圖
          export const getHomeBanner = () => {
              return request({
                  url: '/pc/get_banner'
              })
          }

          之后再在組件中引入調用導出的相關接口方法即可,如:

          import { getHomeBanner } from "../network/api"
          
          getHomeBanner().then(res => {
          	console.log(res)
          })

          以上就是一個簡單的封裝,其中有個攔截請求和攔截響應,可能很多初學的人理解起來有點吃力,我在這里以個人淺見闡述,希望能帶給你些許啟發!

          何為攔截器?

          還是發揮閱讀理解能力,攔截攔截其實就是此路是我開,此樹是我栽,要想過此路,留下買路錢,攔截請求就是比如某些請求需要攜帶一些額外的信息才能訪問,實際項目中最常見的就是需要登錄后才能查看的信息,請求中就必須攜帶token才能訪問,就可以在這里處理,還有攔截響應,比如請求到數據之后,發現不符合要求,先攔下來處理一下,再返回給前端,這就是一個攔截器的基本工作流程!

        19. axios有一個全局攔截的方式:axios.interceptors()
        20. 攔截成功后必須return返回,否則數據無法請求到
        21. 如下所示:

            // 攔截請求,如果獲取某個請求需要攜帶一些額外數據
              instance.interceptors.request.use(
                  config => {
                      console.log(config);
                      return config;
                  }, err => {
                      console.log(err);
                  })
                  
              // 攔截響應
              instance.interceptors.response.use(
                  res => {
                      console.log(res)
                      return res.data
                  }, err => {
                      console.log(err)
                  }
              )

          axios還為我們提供了一些全局配置,如下:

          axios.defaults.baseURL = 'https://api.example.com';
          axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
          axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

          當然也可以將其配置在我們之前創建的axios實例中,使其只作用于某個實例!

          然后來看一下 axios 的所有配置信息:

          數據來自axios中文文檔

          ,一般現在流傳的HTTP請求:GET和POST的比較是這樣的:

          GET和POST是HTTP的兩個常用方法。

          什么是HTTP?

          超文本傳輸協議(HyperText Transfer Protocol -- HTTP)是一個設計來使客戶端和服務器順利進行通訊的協議。

          HTTP在客戶端和服務器之間以request-responseprotocol(請求-回復協議)工作。

          GET- 從指定的服務器中獲取數據

          POST- 提交數據給指定的服務器處理

          GET方法:

          使用GET方法時,查詢字符串(鍵值對)被附加在URL地址后面一起發送到服務器:

          /test/demo_form.jsp?name1=value1&name2=value2

          特點:

          · GET請求能夠被緩存

          · GET請求會保存在瀏覽器的瀏覽記錄中

          · 以GET請求的URL能夠保存為瀏覽器書簽

          · GET請求有長度限制

          · GET請求主要用以獲取數據

          POST方法:

          使用POST方法時,查詢字符串在POST信息中單獨存在,和HTTP請求一起發送到服務器:

          POST/test/demo_form.jsp HTTP/1.1

          Host:w3schools.com

          name1=value1&name2=value2

          特點:

          · POST請求不能被緩存下來

          · POST請求不會保存在瀏覽器瀏覽記錄中

          · 以POST請求的URL無法保存為瀏覽器書簽

          · POST請求沒有長度限制

          GET和POST的區別:

          其他HTTP請求方式

          二,本質上,這些并不是HTTP的GET和POST兩者請求的區別,這些區別是建立在HTML標準對于HTTP協議的用法的約定之上的。

          1. GET和POST與數據如何傳遞沒有關系

          GET和POST是由HTTP協議定義的。在HTTP協議中,Method和Data(URL, Body, Header)是正交的兩個概念,也就是說,使用哪個Method與應用層的數據如何傳輸是沒有相互關系的。

          HTTP沒有要求,如果Method是POST數據就要放在BODY中。也沒有要求,如果Method是GET,數據(參數)就一定要放在URL中而不能放在BODY中。

          那么,網上流傳甚廣的這個說法是從何而來的呢?我在HTML標準中,找到了相似的描述。這和網上流傳的說法一致。但是這只是HTML標準對HTTP協議的用法的約定。怎么能當成GET和POST的區別呢?

          而且,現代的Web Server都是支持GET中包含BODY這樣的請求。雖然這種請求不可能從瀏覽器發出,但是現在的Web Server又不是只給瀏覽器用,已經完全地超出了HTML服務器的范疇了。

          2. HTTP協議對GET和POST都沒有對長度的限制

          HTTP協議明確地指出了,HTTP頭和Body都沒有長度的要求。而對于URL長度上的限制,有兩方面的原因造成:

          1. 瀏覽器。據說早期的瀏覽器會對URL長度做限制。據說IE對URL長度會限制在2048個字符內(流傳很廣,而且無數同事都表示認同)。但我自己試了一下,我構造了90K的URL通過IE9訪問live.com,是正常的。網上的東西,哪怕是Wikipedia上的,也不能信。

          2. 服務器。URL長了,對服務器處理也是一種負擔。原本一個會話就沒有多少數據,現在如果有人惡意地構造幾個幾M大小的URL,并不停地訪問你的服務器。服務器的最大并發數顯然會下降。另一種攻擊方式是,把告訴服務器Content-Length是一個很大的數,然后只給服務器發一點兒數據,嘿嘿,服務器你就傻等著去吧。哪怕你有超時設置,這種故意的次次訪問超時也能讓服務器吃不了兜著走。有鑒于此,多數服務器出于安全啦、穩定啦方面的考慮,會給URL長度加限制。但是這個限制是針對所有HTTP請求的,與GET、POST沒有關系。

          備知識

          前文沒有描述到傳輸和協議直接的層級對應關系,大概補充下網絡通信中數據傳輸對應的協議,首先了解下OSI(開放式系統互聯:Open System InterConnection)七層 模式,及其對應不同層次的協議。

          OSI體系結構TCP/IP相關協議結構應用層HTTP,Telnet,FTP等表示層會話層傳輸層TCP,UDP網絡層IP數據鏈路層物理層

          了解到HTTP協議是建立在TCP連接基礎之上的。HTTP 是一種允許瀏覽器向服務器獲取資源的協議,是 Web 的基礎,通常由瀏覽器發起請求,用來獲取不同類型的文件, 例如 HTML 文件、CSS 文件、JavaScript 文件、圖片、視頻等。此外,HTTP 也是瀏覽器使用最廣的協議。

          我們對HTTP不太了解的話都會存在這樣的疑惑,為什么再次訪問同一站點會比第一次快,登錄過一次后的網站再次訪問就處于登錄狀態等,我們 通過對HTTP請求過程的剖析來解開這些謎團。

          瀏覽器端發起 HTTP 請求流程

          瀏覽器輸入網址:http://time.geekbang.org/index.html,之后會完成什么步驟呢?

          1、構建請求

          首先,瀏覽器構建請求行信息,構建好后,瀏覽器準備發起網絡請求。

          GET /index.html HTTP1.1

          2、查找緩存

          在真正發起網絡請求之前,瀏覽器會先在瀏覽器緩存中查詢是否有要請求的文件。其中,瀏覽器緩存是一種在本地保存資源副本,以供下次請求時直接使用的技術

          當瀏覽器發現請求資源已經存在瀏覽器緩存中存有副本,則會攔截請求并返回該資源副本結束請求。如果查找緩存失敗,則會進入網絡請求。所以會有利于:

          • 緩解服務器端壓力,提升性能
          • 對于網站來說,緩存是實現快速資源加載的重要組成部分,減少了獲取資源的時間。

          3、準備IP地址和端口

          我們通過開頭預備知識和前文也大概了解到了HTTP和TCP的關系。瀏覽器使用 HTTP 協議作為應用層協議,用來封裝請求的文本信息;并使用 TCP/IP 作傳輸層協議將它發到網絡上,所以在 HTTP 工作開始之前,瀏覽器需要通過 TCP 與服務器建立連接。也就是說 HTTP 的內容是通過 TCP 的傳輸數據階段來實現的。

          TCP和HTTP的關系示意圖:

          據此,我們可以知道建立HTTP網絡請求就是,通過URL地址來解析獲取IP和端口信息,建立服務器和TCP連接。我們通過前文《TCP協議》 說到了數據包都是通過IP地址傳輸給接收方的。而我們網站一般的地址都是域名,所以需要把域名和IP地址做映射關系,即解析IP地址的系統“域名系統(DNS)”解析出 IP地址,并獲取對應端口號獲得建立連接的前置條件。換句話說,即瀏覽器請求DNS返回域名對應的IP,而請求DNS時也會查詢DNS數據緩存服務,判斷是否域名已解析過, 如果解析過則查詢直接使用,拿到IP后則判斷URL是否指明端口號,沒有則HTTP協議默認時80端口。

          4、等待TCP隊列

          Chrome 有個機制,同一個域名同時最多只能建立 6 個 TCP 連接,如果在同一個域名下同時有 10 個請求發生,那么其中 4 個請求會進入排隊等待狀態,直至進行中的請求完成。當然,如果當前請求數量少于 6,會直接進入下一步,建立 TCP 連接。

          5、建立TCP連接

          隊列等待結束后,TCP和服務器實現“三次握手”(前文TCP協議有描述),即客戶端和服務器發送三個數據包以確認連接,實現瀏覽器和服務的連接。

          6、發送HTTP請求

          一旦建立了 TCP 連接,瀏覽器就可以和服務器進行通信了。而 HTTP 中的數據正是在這個通信過程中傳輸的。

          HTTP請求數據格式:

          首先瀏覽器會向服務器發送請求行,它包括了請求方法、請求 URI(Uniform Resource Identifier)和 HTTP 版本協議

          其中請求方式有GET,POST,PUT,Delete等,其中常用的POST會用于發送一些數據給服務器,比如登錄網站把用戶信息發送給服務器,一般 這些數據會通過請求體發送。

          在瀏覽器發送請求行命令之后,還要以請求頭形式發送其他一些信息,把瀏覽器的一些基礎信息告訴服務器。比如包含了瀏覽器所使用的操作系統、瀏覽器內核等信息,以及當前請求的域名信息、Cookie等。

          服務器端處理 HTTP 請求流程

          1、返回請求

          curl -i https://time.geekbang.org/

          通過curl工具(或network面板)我們可以了解到服務器返回的數據格式:

          首先服務器會返回響應行,包括協議版本和狀態碼。

          如果出現錯誤,服務器會通過請求行的狀態碼來返回對應的處理結果,例如:

          • 最常用的狀態碼是 200,表示處理成功;
          • 404,表示沒有找到頁面
          • 500,表示服務器錯誤

          正如瀏覽器會隨同請求發送請求頭一樣,服務器也會隨同響應向瀏覽器發送響應頭。響應頭包含了服務器自身的一些信息, 比如服務器生成返回數據的時間、返回的數據類型(JSON、HTML、流媒體等類型),以及服務器要在客戶端保存的 Cookie 等信息。

          響應頭之后,服務器會發送響應體數據,通常包含了HTML的實際內容。以上為服務器響應瀏覽器的過程。

          2、斷開連接

          一旦服務器向客戶端返回了請求數據,它就要關閉 TCP 連接。不過如果瀏覽器或者服務器在其頭信息中加入了:

          Connection:Keep-Alive

          則TCP 連接在發送后將仍然保持打開狀態,這樣瀏覽器就可以繼續通過同一個 TCP 連接發送請求。保持 TCP 連接可以省去下次請求時需要建立連接的時間,提升資源加載速度。 如果一個頁面內嵌的圖片都來自同一web站點,則初始化一個持久連接則可復用減少TCP的連接。

          3、重定向

          重定向返回響應行和響應頭:

          狀態 301 就是告訴瀏覽器,我需要重定向到另外一個網址,而需要重定向的網址正是包含在響應頭的 Location 字段中,接下來,瀏覽器獲取 Location 字段中的地址,并使用該地址重新導航,這就是一個完整重定向的執行流程。

          總結

          通過http請求的完整過程,我們就知道,請求過程中DNS緩緩和頁面資源緩存會被瀏覽器緩存起來,以減少向服務器請求的資源,所以會再次請求站點時速度會快。

          瀏覽器資源緩存處理過程:

          從上圖的第一次請求可以看出,當服務器返回 HTTP 響應頭給瀏覽器時,瀏覽器是通過響應頭中的 Cache-Control 字段來設置是否緩存該資源。通常,我們還需要為這個資源設置一個緩存過期時長,而這個時長是通過 Cache-Control 中的 Max-age 參數來設置的。

          因此在該緩存資源還未過期的情況下, 如果再次請求該資源,會直接返回緩存中的資源給瀏覽器。

          如果緩存過期了,瀏覽器則會繼續發起網絡請求,并且在 HTTP 請求頭中帶上If-None-Match,服務器收到請求頭后,會根據 If-None-Match 的值來判斷請求的資源是否有更新。

          • 如果沒有更新,就返回 304 狀態碼,相當于服務器告訴瀏覽器,這個緩存可以繼續使用。
          • 如果資源有更新,服務器就直接返回最新資源給瀏覽器。

          登錄網站,通過POST方式提交信息給服務器,服務器接收到瀏覽器提交的信息之后,查詢驗證信息正確則會生成表面用戶身份的字符串寫入響應頭的Set-Cookie字段里返回瀏覽器。

          瀏覽器解析響應頭,如有Set-Cookie字段則保存在本地,當用戶再次訪問時,發起HTTP請求前瀏覽器會讀取Cookie數據并寫入請求頭發送到服務器,服務器再次判斷信息,如果 正確則展示用戶登錄狀態及用戶信息。

          最后總結出瀏覽器中的HTTP請求從發起到結束一共經歷了八個階段:構建請求、查找緩存、準備 IP 和端口、等待 TCP 隊列、建立 TCP 連接、發起 HTTP 請求、服務器處理請求、服務器返回請求和斷開連接

          詳細HTTP請求流程:


          主站蜘蛛池模板: 国产精品久久亚洲一区二区| 精品无码综合一区| 国产日韩AV免费无码一区二区三区| 国产精品视频一区二区三区四| 日韩精品午夜视频一区二区三区| 久久久91精品国产一区二区| 一区在线观看视频| 在线一区二区三区| 久久蜜桃精品一区二区三区| 国产精品va无码一区二区| 亚洲AV无码一区二区三区在线观看 | 在线日产精品一区| 久久精品国产一区二区三区肥胖| 香蕉在线精品一区二区| 一区二区精品视频| 视频一区二区中文字幕| 免费在线观看一区| 国产美女视频一区| 狠狠做深爱婷婷综合一区 | 国精品无码一区二区三区在线蜜臀| 精彩视频一区二区| 福利视频一区二区牛牛| 一区二区国产精品| 国产伦精品一区二区免费| 一区二区三区久久精品| 国产精品免费一区二区三区| 爆乳熟妇一区二区三区霸乳| 亚洲AV成人精品日韩一区18p| 一区二区三区在线视频播放| 无码毛片一区二区三区视频免费播放 | 国模一区二区三区| 国产精品伦子一区二区三区| 国产精品一区不卡| 日韩A无码AV一区二区三区| 午夜无码一区二区三区在线观看| 精品人体无码一区二区三区| 国产午夜精品一区二区三区嫩草| 亚洲乱码国产一区三区| 日本内射精品一区二区视频 | 一区二区三区视频观看| 99精品久久精品一区二区|