1. 程式人生 > 其它 >十六、JavaScript網路請求

十六、JavaScript網路請求

一、http協議

  • 網路傳輸協議

    • https

    • http

    • ftp

    • 一般完整的網路地址應該由這三部分組成:協議+地址+埠

  • http協議是網路協議的一種

    • 與伺服器建立連線:需要三次握手

      • 客戶端--->伺服器:傳送請求,第一次握手

        • 客戶端:確認客戶端自己可以正常傳送請求

        • 伺服器:確認客戶端可以正常傳送請求、確認伺服器可以正常接收請求

      • 伺服器--->客戶端:傳送請求,第二次握手

        • 伺服器:確認伺服器可以正常傳送請求

        • 客戶端:確認客戶端可以正常接收請求、確認客戶端可以正常傳送請求、確認伺服器可以正常接收請求

      • 客戶端--->伺服器:傳送請求,第三次握手

        • 伺服器:確認客戶端可以正常接收請求

    • 與伺服器斷開連線:需要四次揮手

      • 客戶端--->伺服器:傳送請求,第一次揮手

        • 告訴伺服器,客戶端要斷開和伺服器的連線了

      • 伺服器--->客戶端:傳送請求,第二次揮手

        • 告訴客戶端,伺服器知道客戶端要斷開連線,並且伺服器準備不再給客戶端發請求

      • 伺服器--->客戶端:傳送請求,第三次揮手

        • 告訴客戶端,這是伺服器的最後一條請求,之後伺服器不會再發送請求了

        • 但是伺服器可以接收請求

      • 客戶端--->伺服器:傳送請求,第四次揮手

        • 告訴伺服器,伺服器傳送的訊息,客戶端已經接收到

        • 並且知道伺服器不會在傳送請求了

        • 客戶端不再接收伺服器的請求

        • 但是客戶端有可能隨時再給伺服器傳送請求

    • 最終狀態

      • 客戶端不再接收請求,但是隨時可能傳送請求

      • 伺服器不再發送請求,但是隨時可以接收請求

二、請求報文和響應報文

http協議在網路傳輸中通過請求報文、響應報文來完成請求過程

  • 請求報文:傳送的請求內容

    • 由四部分構成:請求行、請求頭、請求空行、請求體

    • 在控制檯network中可以看到

  • 響應報文:傳送的響應結果

    • 由三部分構成:響應行、響應頭、響應體

三、前端請求方式

1、form表單

  • action:傳參物件的url路徑地址

  • method:傳參方式 get / post

  • enctype:設定上傳檔案編碼格式

    • application/x-www-form-urlencoded:預設值,只能上傳文字文件

    • multipart/form-data:以二進位制資料流的格式上傳檔案

  • 引數標籤的設定,input、select、textarea

    • name屬性:作為鍵值對的鍵名,來儲存資料,如果多個標籤name屬性值相同,value不同,給name屬性值新增[]

    • value屬性:設定標籤儲存資料

2、a超連結

  • 超連結點選,頁面跳轉,也能實現傳參功能

  • 超連結只能以get方式傳參

  • 超連結傳參有固定的語法格式

    • 在href屬性值,也就是url地址之後,拼接傳參的鍵值對

    • url地址和傳參鍵值對之間使用 ? 問號間隔

    • 鍵值對,鍵名=數值,鍵名和數值都是根據實際專案需求定義的

    • 多個鍵值對之間使用 & 符號做間隔

    • 鍵名和資料,都不要寫引號

1 <a href="https://www.baidu.com?name=張三&age=18">百度</a>

點選a標籤不會跳轉

 1 <a href="https://www.baidu.com" onclick="return push('/test')">百度</a>
 2 
 3 <script src="https://cdn.bootcss.com/history/4.7.2/history.js"></script>
 4 <script>
 5   let history = History.createBrowserHistory()
 6     function push(path){
 7     history.push(path)
 8     return false
 9   }
10 </script>

3、ajax方式

form表單、超連結發起請求都需要跳轉頁面,ajax方式不需要頁面跳轉

ajax傳參,都是非同步程式,不影響同步程式的執行

1、ajax使用基本步驟

需要建立一個 ajax 物件

1 const xhr = new XMLHttpRequest();

配置請求內容和資料

  • get方式可以在請求地址之後直接拼接傳參的鍵值對

  • post方式在 open 中只定義請求url地址

1 xhr.open( '請求方式get/post', '請求地址?鍵名=數值&鍵名=數值' );

傳送請求

1 xhr.send();
  • post請求在 send() 階段來定義引數
1 // 1、定義請求頭資訊
2 xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
3 
4 // 2、定義引數,xhr.send(以字串形式傳遞引數)
5 xhr.send('name=張三&age=18');

接收請求結果,響應體內容

1 xhr.onload = function(){}

2、ajax的相容處理

建立ajax物件

 1 // 標準瀏覽器
 2 // const xhr = new XMLHttpRequest();
 3 
 4 // 低版本IE瀏覽器
 5 // const xhr = new ActiveXObject('Microsoft.XMLHTTP');
 6 
 7 // 相容語法
 8 let xhr;
 9 if (XMLHttpRequest) {
10   xhr = new XMLHttpRequest();
11 } else {
12   xhr = new ActiveXObject('Microsoft.XMLHTTP');
13 }

定義傳參物件url地址

1 xhr.open();

傳送請求

1 xhr.send();

接受請求

 1 // 標準瀏覽器 
 2 // xhr.onload = function(){}
 3 
 4 // 低版本IE瀏覽器
 5 // 判斷狀態碼是否是 200 - 299,判斷請求步驟是否已經結束
 6 // 當請求步驟發生改變時,觸發函式程式
 7 xhr.onreadystatechange = function () {
 8   // 判斷請求步驟數值是4,表示請求結束
 9   // 判斷http的請求狀態碼是200-299表示請求成功,此時,判斷請求成功並且接收響應體內容
10   // 以2開頭之後跟2位數值 --- 2開始的三位數
11   // /^2\d{2}&/.test(xhr.status)
12   if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status <= 299)) {
13     // 資料處理
14   }
15 }

ajax的請求步驟

  • 同步

    • 0 --- 建立ajax物件

    • 1 --- 設定ajax請求地址和請求方式

  • 非同步

    • 2 --- 傳送ajax請求

    • 3 --- 接收ajax響應報文,解析響應體中的內容

    • 4 --- ajax請求完全結束,並且響應體內容解析完成

4、fetch

  • 由HTML5提供的內建API

  • 更加簡單的資料獲取方式,功能更強大、靈活,可以看作是xhr的升級版

  • 基於Promise實現

  • fetch支援很多請求方式,但預設為GET請求,如果需要使用其他方式可以通過第二個自選引數的method選項去指定

語法結構

1 fetch(url,[some settings]).then(fn2)
2       .then(fn3)
3       ...
4       .catch(fn)

用法示例

1 fetch("http://xxx/?id=123")
2   .then(
3     res => {
4       console.log(res)
5       res.json()
6     })
7   .catch(err => {})
1 // 1、通過url表示式來傳遞資料
2 fetch("http://xxx/?id=123")
3     .then(res => res.json())
4     .then(data => console.log(data));
 1 // 2、post標準提交
 2 fetch("http://xxxx/post", {
 3     method: "post",
 4     body: "uname=lisi&pwd=123",
 5     headers: {
 6         "Content-Type": "application/x-www-form-urlencoded",
 7     },
 8     })
 9     .then(res => res.json())
10     .then(data => console.log(data));
 1 // 3、post提交json資料
 2 fetch("http://localhost:3000/books", {
 3     method: "post",
 4     body: JSON.stringify({
 5         uname: "lisi",
 6         pwd: "123",
 7     }),
 8     headers: {
 9         "Content-Type": "application/json",
10     },
11 })
12     .then(res => res.json())
13     .then(data => console.log(data));

注意:fetch 不會發送 cookies。除非你使用了credentials 的初始化選項credentials: "include"

fetch的響應結果處理方法

  • json():返回結果和JSON.parse(responseText)一樣

  • text():將返回體處理成字串型別

四、響應狀態碼

  • 100 - 199:表示連線已經正常建立,正在持續保持連線中

  • 200:連線請求已經結束,成功

  • 3XX【重定向系列的狀態碼】

    • 301:永久重定向

    • 302:臨時重定向

    • 307:內部瀏覽器(快取)重定向

  • 4XX【錯誤系列】

    • 400:bad request,錯誤請求

    • 401:鑑權失敗

    • 403:禁止訪問

    • 404:找不到對應的資源

    • 405:方法不被允許

  • 5XX【伺服器錯誤,環境問題】

    • 500:伺服器內部錯誤(程式碼、環境問題)

    • 502:bad Getway,錯誤閘道器

五、跨域問題

  • 瀏覽器的同源性

    • 同源指的是兩個請求的檔案,必須是,同一個專案

    • 同一個專案:請求物件的url地址必須與請求發起檔案完全相同

    • 在瀏覽器處理請求時預設執行的是同源策略

    • 也就是瀏覽器只允許同源的專案/請求之間獲取響應體內容

    • 如果不是同源的請求,只允許瀏覽html檔案等,不允許獲取響應體

  • jsonp

    • 利用script標籤沒有跨域限制,通過src屬性,設定跨域請求地址,請求內容按照 js程式格式執行

    • 請求方式只能是get方式,可以在url請求地址後,拼接資料傳參

  • cors

    • 後端幫助我們解決跨域的方式

  • 伺服器代理

    • proxy

    • 正向代理

      • 縮短訪問時間:提高訪問執行效率

      • 分擔訪問負荷:防止主伺服器訪問量過大,直接崩潰

      • 客戶端發起請求,實際上訪問的是代理伺服器,客戶端不知道訪問的是哪個具體的伺服器

    • 反向代理

      • 伺服器響應請求,也是傳送給代理伺服器,並不是直接傳送給客戶端

      • 主伺服器只能看到代理伺服器傳送的請求,看不到客戶端傳送的請求

六、常見請求方式

1、get請求

  • get請求攜帶的資料,儲存在位址列中

  • 搜尋資料時使用get請求

  • 位址列內,儲存字串的長度有限的,導致get方式傳引數據內容大小有限制

  • 會被瀏覽器自動快取儲存

    • 如果兩次get請求內容相同,瀏覽器不會執行第二次get請求

    • 會使用上一次get請求的響應結果內容

    • 實際專案中,往往關閉get自動快取功能/或者新增一個時間戳讓請求不同

2、post請求

  • post攜帶的資料,儲存在請求體中

  • 除了搜尋資料之外,其他情況都使用post請求

  • post請求方式,將資料儲存在請求體中,理論上可以無限傳遞資料,但是實際情況中,會受到伺服器限制要求

  • post請求不會被瀏覽器自動快取

  • 其他請求方式,本質上還是 post 請求,只是帶語義化

    • PUT

    • DELETE

    • HEAD

    • PATCH

    • OPTION

    • CONNECT

七、json字串

  • json字串是一種特殊的字串

  • 每一種計算機語言都有自己特定的 json 字串

  • 作為各種計算機語言之間的通用語言

  • JavaScript的json字串語法

    • JSON.stringify():將其他資料型別轉化為 json字串

    • JSON.parse():將json字串,還原為對應的資料型別