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 亚洲天堂二区,国产伦久视频免费观看视频,99re在线精品视频免费

          整合營銷服務商

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

          免費咨詢熱線:

          前后端數據交互(四)-fetch 請求詳解

          etch 是 XMLHttpRequest 的升級版,使用js腳本發出網絡請求,但是與 XMLHttpRequest 不同的是,fetch 方式使用 Promise,相比 XMLHttpRequest 更加簡潔。所以我們告別XMLHttpRequest,引入 fetch 如何使用?

          一、fetch介紹

          fetch() 是一個全局方法,提供一種簡單,合理的方式跨網絡獲取資源。它的請求是基于 Promise 的,需要詳細學習 Promise ,請點擊《 Promise詳解 》。它是專門為了取代傳統的 xhr 而生的。

          1.1、fetch使用語法

          fetch(url,options).then((response)=>{
          //處理http響應
          },(error)=>{
          //處理錯誤
          })

          url :是發送網絡請求的地址。

          options:發送請求參數,

          • body - http請求參數
          • mode - 指定請求模式。默認值為cros:允許跨域;same-origin:只允許同源請求;no-cros:只限于get、post和head,并且只能使用有限的幾個簡單標頭。
          • cache - 用戶指定緩存。
          • method - 請求方法,默認GET
          • signal - 用于取消 fetch
          • headers - http請求頭設置
          • keepalive - 用于頁面卸載時,告訴瀏覽器在后臺保持連接,繼續發送數據。
          • credentials - cookie設置,默認omit,忽略不帶cookie,same-origin同源請求帶cookie,inclue無論跨域還是同源都會帶cookie。

          1.2、response 對象

          fetch 請求成功后,響應 response 對象如圖:

          • status - http狀態碼,范圍在100-599之間
          • statusText - 服務器返回狀態文字描述
          • ok - 返回布爾值,如果狀態碼2開頭的,則true,反之false
          • headers - 響應頭
          • body - 響應體。響應體內的數據,根據類型各自處理。
          • type - 返回請求類型。
          • redirected - 返回布爾值,表示是否發生過跳轉。

          1.3、讀取內容方法

          response 對象根據服務器返回的不同類型數據,提供了不同的讀取方法。分別有:

          1. response.text() -- 得到文本字符串
          2. response.json() - 得到 json 對象
          3. response.blob() - 得到二進制 blob 對象
          4. response.formData() - 得到 fromData 表單對象
          5. response.arrayBuffer() - 得到二進制 arrayBuffer 對象

          上述 5 個方法,返回的都是 promise 對象,必須等到異步操作結束,才能得到服務器返回的完整數據。

          1.4、response.clone()

          stream 對象只能讀取一次,讀取完就沒了,這意味著,上邊的五種讀取方法,只能使用一個,否則會報錯。

          因此 response 對象提供了 clone() 方法,創建 respons 對象副本,實現多次讀取。如下:將一張圖片,讀取兩次:

          const response1 = await fetch('flowers.jpg');
          const response2 = response1.clone();
          
          const myBlob1 = await response1.blob();
          const myBlob2 = await response2.blob();
          
          image1.src = URL.createObjectURL(myBlob1);
          image2.src = URL.createObjectURL(myBlob2);

          1.4、response.body()

          body 屬性返回一個 ReadableStream 對象,供用戶操作,可以用來分塊讀取內容,顯示下載的進度就是其中一種應用。

          const response = await fetch('flower.jpg');
          const reader = response.body.getReader();
          while(true) {
            const {done, value} = await reader.read();
            if (done) {
              break;
            }
            console.log(`Received ${value.length} bytes`)
          }

          response.body.getReader() 返回一個遍歷器,這個遍歷器 read() 方法每次都會返回一個對象,表示本次讀取的內容塊。

          二、請求時 POST 和 GET 分別處理

          請求方式不同,傳值方式也不同。xhr 會分別處理 get 和 post 數據傳輸,還有請求頭設置,同樣 fetch 也需要分別處理。

          2.1、get 方式

          只需要在url中加入傳輸數據,options中加入請求方式。如下面代碼所示:

          <input type="text" id="user"><br>
          <input type="password" id="pas"><br>
          <button onclick="login()">提交</button>
          <script>
           function login(){
            fetch(`http://localhost:80/fetch.html?user=${user.value}&pas=${pas.value}`,{
             method:'GET'
            }).then(response=>{
             console.log('響應',response)
            })
           }
          </script>

          2.2、post 方式

          使用 post 發送請求時,需要設置請求頭、請求數據等。

          將上個實例,改寫成 post 方式提交數據,代碼如下:

          fetch(`http://localhost:80/ES6練習題/53fetch.html`,{
           method:'POST',
           headers:{
            'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'
           },
           body:`user=${user.value}&pas=${pas.value}`
           }).then(response=>{
            console.log('響應',response)
          })

          如果是提交json數據時,需要把json轉換成字符串。如

          body:JSON.stringify(json)

          如果提交的是表單數據,使用 formData轉化下,如:

          body:new FormData(form)

          上傳文件,可以包含在整個表單里一起提交,如:

          const input = document.querySelector('input[type="file"]');
          
          const data = new FormData();
          data.append('file', input.files[0]);
          data.append('user', 'foo');
          
          fetch('/avatars', {
            method: 'POST',
            body: data
          });

          上傳二進制數據,將 bolb 或 arrayBuffer 數據放到body屬性里,如:

          let blob = await new Promise(resolve =>   
            canvasElem.toBlob(resolve,  'image/png')
          );
          
          let response = await fetch('/article/fetch/post/image', {
            method:  'POST',
            body: blob
          });

          三、fetch 常見坑

          3.1、fetch兼容性

          fetch原生支持率如圖:

          fetch 是相對較新的技術,IE瀏覽器不支持,還有其他低版本瀏覽器也不支持,因此如果使用fetch時,需要考慮瀏覽器兼容問題。

          解決辦法:引入 polyfill 完美支持 IE8 以上。

          • 由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
          • 引入 Promise 的 polyfill:es6-promise
          • 引入 fetch 探測庫:fetch-detector
          • 引入 fetch 的 polyfill: fetch-ie8
          • 可選:如果你還使用了 jsonp,引入 fetch-jsonp
          • 可選:開啟 Babel 的 runtime 模式,現在就使用 async/await

          polyfill 的原理就是探測fetch是否支持,如果不支持則用 xhr 實現。支持 fetch 的瀏覽器,響應中文會亂碼,所以使用 fetch-detector 和 fetch-ie8 解決亂碼問題。

          3.2、fetch默認不帶cookie

          傳遞cookie時,必須在header參數內加上 credentials:'include',才會像 xhr 將當前cookie 帶有請求中。

          3.3、異常處理

          fetch 不同于 xhr ,xhr 自帶取消、錯誤等方法,所以服務器返回 4xx 或 5xx 時,是不會拋出錯誤的,需要手動處理,通過 response 中的 status 字段來判斷。

          avaScript 初學者學完語法,進入實際的網頁編程,一定有人告訴你,要掌握一個叫做 XMLHttpRequest 的東西。

          腳本都靠它發出 HTTP 請求,跟服務器通信。所謂的 AJAX 操作就是基于它實現的。要是沒有它,就不會有單頁應用。

          這個 XMLHttpRequest 對象,不僅名字怪,用法也非常獨特。

          let xhr = new XMLHttpRequest;xhr.open('GET', url)xhr.onload = function  { if (this.status === 200) { let data = JSON.parse(this.responseText); console.log(data); }};xhr.onerror = function (err) { console.log('Error Occurred :', err);}xhr.send;

          就是因為寫起來麻煩,實際開發中,往往使用它的各種封裝庫,比如早期的 jQuery。

          $.get("test.php", function (data) { $("body") .append("Name: " + data.name)  .append("Time: " + data.time);}, "json");

          早期的封裝庫都使用回調函數,很不直觀。后來的封裝庫都改用 Promise 的寫法,比如 axios。

          axios.get('/user?ID=12345') .then(function (response) { // handle success console.log(response); }) .catch(function (error) { // handle error console.log(error); })

          這樣用起來,確實方便了,但是需要加載外部庫,而它又是一個天天用到的基本需求。所以,瀏覽器廠商最終決定,拋棄 XMLHttpRequest,另起爐灶,重寫一套全新的 API,內置在瀏覽器里面。

          這就是 Fetch API,它使用fetch發出請求,返回的是 Promise 對象。

          fetch('https://api.github.com/users/ruanyf') .then(response => response.json) .then(json => console.log(json)) .catch(err => console.log('Request Failed', err)); 

          Promise 可以使用 await 語法,表達起來跟同步操作一模一樣。

          async function getJSON { let url = 'https://api.github.com/users/ruanyf'; try { let response = await fetch(url); return await response.json; } catch (error) { console.log('Request Failed', error); }}

          Fetch API 的優點是寫法簡單,缺點是這個 API 包含的內容非常多,想要完全掌握并不容易。

          我一直想寫一篇教程,完整介紹它的各種用法,便于自己使用的時候查找。現在終于寫出來,以后可以告別 XMLHttpRequest 了。

          http://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html

          (完)

          etch()方法

          ECMAscript官方繼續推出了一個基于Promise的請求方法, 更簡單, 更便捷。

          就是fetch()方法,這個方法可以替代傳統Ajax請求, 返回Promise的實例。

          fetch()函數是ECMAscript提出的新的特性, 它:

          能夠發出Ajax請求, 并且請求原理不是xhr, 而是新的原理;

          天生可以跨域, 但是需要設置頭, 服務器可以寫腳本識別這個頭部判斷是否應該拒絕它;

          fetch()返回Promise對象, 所以可以用then和catch方法, then方法的第一個函數是resolve, 這個resolve的返回值將自動被await等號左邊的變量的接收。

          必須寫async和await。

          fetch的語法

          fetch(url)
          .then(res => console.log(res))
          .then(res => console.log(res))

          .catch(err => console.log(err));

          使用場景1

          async function main(){
          //請求回來的數據都存在body中,作為一種可讀的流返回,要使用json方法轉換
          var data1 = await fetch("data/1.json").then(data=>data.json());
          var data2 = await fetch("data/2.json").then(data=>data.json());
          var data3 = await fetch("data/3.json").then(data=>data.json());
          console.log(data1)
          console.log(data2)
          console.log(data3)
          };
          main();

          使用場景2

          // 請求JSON數據
          async function getUsers(){
          const res = await fetch("https://www.xxx.com");
          const data = await res.json();
          return data;
          }
          getUsers()
          .then((users) => console.log(users))
          .catch((err) => console.log(err))

          可以不用jQuery了!傳統Ajax已死,fetch永生。

          兼容性注意:

          babel沒有任何插件可以翻譯fetch為傳統Ajax。

          fetch只能用在瀏覽器環境, 不能用在Nodejs環境。

          fetch請求的兩種數據格式

          html結構:

          <div>
          <button id="btn1">請求本地文本數據</button>
          <button id="btn2">請求網絡json數據</button>
          <div id="output"></div>
          </div>

          JavaScript邏輯:

          <script>

          document.getElementById('btn1').addEventListener('click', getText);
          document.getElementById('btn2').addEventListener('click', getJson);
          // 獲取本地純文本數據
          function getText(){
          fetch("test.txt").then(res => res.text())
          .then(data => {console.log(data)})
          .catch(err => console.log(err));
          }
          // 獲取json數據
          function getJson(){
          fetch("posts.json")
          .then(res => res.json())
          .then(data => { console.log(data)})
          .catch(err => console.log(err));
          }
          </script>

          fetch方法的配置

          fetch()方法的第二個參數是配置參數, 可以配置發送POST/PUT/DELETE等請求類型。

          fetch('url', [options]);

          實踐中, post請求會像下面這樣:

          fetch('url', {
          method: 'post',
          headers: {
          'Content-Type': 'application/json'
          },
          body: JSON.stringify({name:'小明'})
          })
          .then(data=>{console.log(data)})
          .catch(err=>{console.log(err)})

          method請求類型參數:

          設置請求方式(如POST | PUT | DELETE), fetch默認請求方式為GET。

          headers請求頭參數

          向服務器說明希望的到什么待遇, 這里主要用到Content-Type

          因為一般使用JSON數據格式, 所以設置Content-Type為application/json

          body參數設置報文體

          要發送給后端的內容, 如果發送JSON數據, 必須調用JSON.stringify()方法。

          credentials證書參數

          因為默認情況下, fetch不會從服務端發送或接收任何cookies, 所以可以配置以下參數指定發送cookies的情況, 默認值:same-origin, 以下為可選值:

          omit: 不發送cookies

          same-origin: 在同域情況下發送cookies

          include: 同域或跨域都發送cookies

          可以理解為:

          跨域請求是否提供憑據信息(cookie、HTTP認證及客戶端SSL證明等)

          也可以簡單的理解為, 當前請求為跨域類型時是否在請求中協帶cookie。

          基于Promise封裝fetch請求庫

          用ES6的class類封裝一個函數

          app.js

          /*
          * 基于Promise封裝fetch請求庫
          */
          class FetchHttp{
          // 封裝get請求
          get(url){
          return new Promise((resolve,reject)=>{
          fetch(url)
          .then(data => resolve(data.json()))
          .catch(err => reject(err))
          })
          }
          // 封裝post請求
          post(url, data){
          return new Promise((resolve, reject)=>{
          fetch(url, {
          method:"POST",
          headers:{'Content-type':'application/json'},
          body:JSON.stringify(data)
          })
          .then(data => resolve(data.json()))
          .catch(err => reject(err))
          })
          }
          // 封裝put請求
          put(url, data){
          return new Promise((resolve, reject)=>{
          fetch(url, {
          method:"PUT",
          headers:{'Content-type':'application/json'},
          body:JSON.stringify(data)
          })
          .then(data => resolve(data.json()))
          .catch(err => reject(err))
          })
          }
          // 封裝delete請求
          delete(url){
          return new Promise((resolve, reject)=>{
          fetch(url, {
          method:"DELETE",
          headers:{'Content-type':'application/json'},
          })
          .then(data => resolve('數據刪除成功!'))
          .catch(err => reject(err))
          })
          }
          }
          <!DOCTYPE html>
          <html lang="en">
          <head>
          <meta charset="UTF-8" />
          <title>Document</title>
          </head>
          <body>
          </body>
          <script src="js/app.js"></script>
          <script>
          const http = new FetchHttp; //引入函數
          const data = {
          name:"小明",
          sex:"男",
          age:29
          }
          http.delete("https://www.xxx.com")
          .then(data=>{console.log(data)})
          .catch(err=>{console.log(err)})
          </script>
          </html>


          基于async封裝fetch請求庫app.js


          主站蜘蛛池模板: 精品女同一区二区三区在线| 亚洲熟女少妇一区二区| 久久精品亚洲一区二区| 日本中文字幕在线视频一区| 精品欧洲av无码一区二区| 国偷自产Av一区二区三区吞精| 亚洲AV无码一区二区三区电影| 精品一区二区三区无码免费视频| 久久久精品一区二区三区| 精品无码人妻一区二区三区不卡| 国产在线步兵一区二区三区| 精品一区二区三人妻视频| 精品日韩亚洲AV无码一区二区三区| 日本不卡一区二区视频a| 国产免费无码一区二区| 中文字幕一区二区在线播放| 国产伦精品一区二区免费| 一区二区三区美女视频| 日韩一区二区精品观看| 色系一区二区三区四区五区 | 国产精华液一区二区区别大吗| 国产福利无码一区在线| 好爽毛片一区二区三区四无码三飞| 无码少妇一区二区| 亚洲电影一区二区| 精品福利视频一区二区三区 | 国产经典一区二区三区蜜芽| 亚洲国产综合无码一区| 国产一区二区免费视频| 精品一区二区三区自拍图片区| 中文字幕在线看视频一区二区三区| 久久久久人妻精品一区二区三区| 人妻夜夜爽天天爽爽一区| 亚洲av综合av一区二区三区| 国语对白一区二区三区| 精品一区二区三区3d动漫| 久久亚洲中文字幕精品一区| 精品亚洲一区二区| 美女毛片一区二区三区四区| 日韩福利视频一区| 国产成人无码AV一区二区|