ajax - xhr level2新特性 json等眾多內容

語言: CN / TW / HK

1.

今天的內容其實挺多的,我們慢慢來說。首先第一個是xhr的基本使用,什麼是xhr?

XMLHTTPRequest是瀏覽器提供的js物件,可以請求伺服器上的資料資源,包括我們前面一直用的jq裡面的三個請求資源的方法都是基於xhr來封裝的。

那麼首先我們看到xhr的get請求怎麼來實現

首先要建立xhr例項通過new來實現

然後呼叫open函式,裡面值為請求方式以及url

第三步呼叫send函式

第四步監聽onreadyStateChange事件在這個事件裡面要注意一下請求狀態和伺服器響應狀態的固定寫法,還有伺服器響應回的資料

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1.建立xhr物件
        var xhr = new XMLHttpRequest()
        // 2.呼叫open函式 決定請求方式和url
        xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks')
        // 3.呼叫send函式
        xhr.send()
        // 4.監聽事件
        xhr.onreadystatechange = function() {
            // 4.1注意請求狀態和伺服器響應狀態固定寫法
            if (xhr.readyState ==4 && xhr.status == 200) {
                // 4.2獲取相應的資料
                console.log(xhr.response);
            }
        }
    </script>
</body>
</html>0.2
1

我們看到在監聽請求狀態變化事件裡有一個readystate的屬性這個屬性表示ajax當前請求所處的狀態,其中0表示xhr物件以建立,但請求未呼叫open。1表示已呼叫open函式。2表示已呼叫send函式。3表示資料接收中。最後4表示一切請求完成

那麼xhr帶參的get請求怎麼來實現的呢?只需要在open函式的url裡面接一個查詢字串即可

xhr.open('get', 'http://www.ssfddaf.com/api?name=%df%fd%gf')

那麼什麼是查詢字串?

在url末尾加上?引數=值多個引數間用&來連線這就是查詢字串,無論是jQuery的三個請求方式還是xhr指定的引數其本質都是在url後帶查詢字串

這裡還要了解一個點url編碼與解碼

url中只允許出線英文不允許中文等其他語種,所以他就會把除英文外其他語種轉換為%開頭帶兩個字元的樣式來代替

編碼encodeURI('中文;)               解碼decodeURI(%的字元)三組%表示一箇中文

2.

接下來我們看到xhr怎麼發起post請求

第一步建立物件

第二部open函式把請求方式改為post

第三步設定content-type 這是一個固定寫法

xhr.setRequestHeader(‘content-type’, ‘application/x-www-form-urlencoded’)

第四步呼叫send函式 post的引數在這裡新增以查詢字串的方式新增進來

第五步監聽事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1.建立xhr物件
        var xhr = new XMLHttpRequest()
        // 2.呼叫open函式
        xhr.open('post', 'http://www.liulongbin.top:3006/api/addbook')
        // 3.設定cententtype
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
        // 4.呼叫send函式
        xhr.send('bookname=水府傳&author=我')
        // 5.監聽事件
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                console.log(xhr.responseText);
            }
        }
    </script>
</body>
</html>

3.

資料交換格式

即伺服器與客戶端之間進行資料傳輸與交換的格式,XML和JSON這兩種

XML我們用的比較少,它是可擴充套件標記語言,跟html很相似

JSON

什麼事json,就是js物件和陣列的字串表示法,其中本質還是一個字串它是輕量級文字資料交換格式

它的結構為有兩種物件結構和陣列結構

物件結構

‘{key:value}’咋一看跟物件很相似,但是首先外面會有引號,其次鍵值是字元型別必須加雙引號

陣列結構

【a,a】

要注意的是鍵值的雙引號,json中不能寫註釋,不能使用undefined和函式作為值

json和物件互轉

obj = JSON.parse(json)(反序列化)

json = JSON.stringify(obj)(序列化)

4.

封裝自己的ajax函式

①先封裝一個處理data物件為查詢字串的函式

②封裝函式xhr

③判斷不同的請求型別達到不同的方式

這個總之記住一點就是xhr呼叫請求的總體步驟就沒得問題

 // 1.先封裝函式處理傳進來的引數為查詢字串
        function revolveData(data) {
            var arr = []
            for (var k in data) {
                arr[arr.length] = k + '=' + data[k]
            }
            var str = arr.join('&')
            return str
        }
// console.log(revolveData({name : '張三', age : 19}));
// 2。封裝主體函式
function ajaxMine(obj) {
    var xhr = new XMLHttpRequest()
    var str = revolveData(obj.data)
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var res = JSON.parse(xhr.response)
            obj.success(res)
        }
    }
    // 3.判斷不同的請求,做到不同的操作
    if (obj.method.toUpperCase() == 'GET') {
        xhr.open(obj.method, obj.url + '?' +str)
        xhr.send()
    } else if (obj.method.toUpperCase() == 'POST') {
        xhr.open(obj.method, obj.url)
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
        xhr.send(str)
    }
}

驗證

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./封裝自己的ajax函式.js"></script>
    <script>
        /* ajaxMine({
            method : 'get',
            url : 'http://www.liulongbin.top:3006/api/getbooks',
            data : {
                id : 2
            },
            success : function(res) {
                console.log(res);
            }
        }) */
        ajaxMine({
            method : 'post',
            url : 'http://www.liulongbin.top:3006/api/addbook',
            data : {
                bookname : '收首飾',
                author : '東風似舊',
                publisher : '身法'
            },
            success : function(res) {
                console.log(res);
            }
        }) 
    </script>
</body>
</html>

5.

xhr level2新特性

在我們舊版的xhr缺點就是不支援檔案上傳而且沒有進度資訊只有完沒完成

在我們新版xhr

支援檔案上傳,有進度資訊,還可以設定http時限,還可使用formdata物件管理表單資料

接下來我會一一開始xhr這四個新特性

5.1

首先第一個設定Http時限,也就是在規定時間如果還沒有完成請求任務那麼這個請求就失敗了

xhr.timeout = 2000

與之對應的還有一個ontimeout的事件在超時後會做些什麼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var xhr = new XMLHttpRequest()
        xhr.timeout = 50
        xhr.ontimeout = function() {
            console.log('請求超時了');
        }
        xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks')
        xhr.send()
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                console.log(xhr.responseText);
            }
        }
    </script>
</body>
</html>

5..2

formdata管理表單

因為我們ajax主要是用來提交表單資料的嘛,所以H5就新增了一個FormData物件用來模擬表單操作

①新建formdata物件

②為formdata新增表單項

③建立xhr

④用xhr完成請求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1.建立FormData物件
        var fd = new FormData()
        // 2.往裡面新增表單項
        fd.append('uname', '王五')
        fd.append('age' , 29)
        // 3,建立xhr物件
        var xhr = new XMLHttpRequest()
        // 4.使用xhr物件制定請求型別與地址
        xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata')
        // 5.直接提交,formdata物件,這與提交網頁表單的效果完全一樣
        xhr.send(fd)
        // 6.驗證
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                console.log(xhr.responsete);
            }
        }
    </script>
</body>
</html>

formdata還有一個用法,就是可以用來獲取表單的值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="">
        <input type="text" name="uname">
        <input type="password" name="pwd">
        <input type="submit" value="提交">
    </form>
    <script>
        var  form = document.querySelector('form')
        form.onsubmit = e => {
            e.preventDefault()
            var xhr = new XMLHttpRequest()
            var fd = new FormData(form)
            xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata')
            xhr.send(fd)
            xhr.onreadystatechange = () => {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    console.log(xhr.responseText);
                }
            }
        }
    </script>
</body>
</html>

5.3

上傳檔案

①定義UI結構

②驗證是否選擇了檔案

③像formdata追加檔案

④用xhr發起上傳請求

⑤監聽事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
     <!-- 1.定義ui結構 -->
     <!-- 1.1檔案選擇框 -->
     <input type="file">
     <!-- 1.2上傳按鈕 -->
     <input type="submit" value="上傳檔案">
     <!-- 1.3img標籤 用來顯示上傳成功後的圖片 -->
     <img src="" alt="">
     <script>
        //  2.驗證是否上傳了檔案
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1注意這裡這個。files它是一個數組存放的是檔案
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3.像formdata中追加檔案
                var fd = new FormData()
                // avator為頭像假裝這裡是上傳的頭像
                fd.append('avatar', files[0])

                // 4.使用xhr發起上傳檔案請求
                var xhr = new XMLHttpRequest()
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5.監聽事件
                xhr.onreadystatechange = () => {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {
                            document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {
                            console.log('上傳檔案失敗');
                        }
                    }
                }
            } else {
               return alert('請上傳檔案')
            }
        })
     </script>
</body>
</html>

5.4

顯示上傳進度

通過xhr.upload.onprogress事件來監聽這裡面有三個屬性值得注意一下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
     <!-- 1.定義ui結構 -->
     <!-- 1.1檔案選擇框 -->
     <input type="file">
     <!-- 1.2上傳按鈕 -->
     <input type="submit" value="上傳檔案">
     <!-- 1.3img標籤 用來顯示上傳成功後的圖片 -->
     <img src="" alt="">
     <script>
        //  2.驗證是否上傳了檔案
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1注意這裡這個。files它是一個數組存放的是檔案
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3.像formdata中追加檔案
                var fd = new FormData()
                // avator為頭像假裝這裡是上傳的頭像
                fd.append('avatar', files[0])

                // 4.使用xhr發起上傳檔案請求
                var xhr = new XMLHttpRequest()
                
                // --------------------------------
                // 1.上傳進度監聽事件
                xhr.upload.onprogress = e => {
                    // 2.引數一 e.lengthComputable是一個布林值,表示當前上傳的資源是否具有可計算的長度要有才能進去
                    if (e.lengthComputable) {
                        // 引數二e.loaded已傳輸的位元組
                        // 引數三e.total需傳輸的總位元組
                        var percenComplete = Math.ceil((e.loaded / e.total) * 100)
                        console.log(percenComplete);
                    }
                }
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5.監聽事件
                xhr.onreadystatechange = () => {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {
                            document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {
                            console.log('上傳檔案失敗');
                        }
                    }
                }
            } else {
               return alert('請上傳檔案')
            }
        })
     </script>
</body>
</html>

知道了上傳進度我們就可以通過bootstrap來一個進度條板的上傳進度

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../day01/lib/bootstrap.css">
</head>
<body>
     <!-- 1.定義ui結構 -->
     <!-- 1.1檔案選擇框 -->
     <input type="file">
     <!-- 1.2上傳按鈕 -->
     <input type="submit" value="上傳檔案">
     <!-- 1.3img標籤 用來顯示上傳成功後的圖片 -->
     <img src="" alt="">

     <!-- 進度條 -->
     <div class="progress" style="width: 500px;">
        <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
          0%
        </div>
      </div>
     <script>
        //  2.驗證是否上傳了檔案
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1注意這裡這個。files它是一個數組存放的是檔案
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3.像formdata中追加檔案
                var fd = new FormData()
                // avator為頭像假裝這裡是上傳的頭像
                fd.append('avatar', files[0])

                // 4.使用xhr發起上傳檔案請求
                var xhr = new XMLHttpRequest()
                
                // --------------------------------
                // 1.監聽事件
                var program = document.querySelector('.progress-bar')
                xhr.upload.onprogress = e => {
                    // 2.引數一 e.lengthComputable是一個布林值,表示當前上傳的資源是否具有可計算的長度要有才能進去
                    if (e.lengthComputable) {
                        // 引數二e.loaded已傳輸的位元組
                        // 引數三e.total需傳輸的總位元組
                        var percenComplete = Math.ceil((e.loaded / e.total) * 100)
                        // console.log(percenComplete);
                        program.style.width = percenComplete + '%'
                        program.innerText = '%' + percenComplete 
                    }
                }
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5.監聽事件
                xhr.onreadystatechange = () => {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {
                            document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {
                            console.log('上傳檔案失敗');
                        }
                    }
                }
            } else {
               return alert('請上傳檔案')
            }
        })
     </script>
</body>
</html>

最後完善上傳成功的進度條

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../day01/lib/bootstrap.css">
</head>
<body>
     <!-- 1.定義ui結構 -->
     <!-- 1.1檔案選擇框 -->
     <input type="file">
     <!-- 1.2上傳按鈕 -->
     <input type="submit" value="上傳檔案">
     <!-- 1.3img標籤 用來顯示上傳成功後的圖片 -->
     <img src="" alt="">

     <!-- 進度條 -->
     <div class="progress" style="width: 500px;">
        <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
          0%
        </div>
      </div>
     <script>
        //  2.驗證是否上傳了檔案
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1注意這裡這個。files它是一個數組存放的是檔案
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3.像formdata中追加檔案
                var fd = new FormData()
                // avator為頭像假裝這裡是上傳的頭像
                fd.append('avatar', files[0])

                // 4.使用xhr發起上傳檔案請求
                var xhr = new XMLHttpRequest()
                
                // --------------------------------
                // 1.監聽事件
                var program = document.querySelector('.progress-bar')
                xhr.upload.onprogress = e => {
                    // 2.引數一 e.lengthComputable是一個布林值,表示當前上傳的資源是否具有可計算的長度要有才能進去
                    if (e.lengthComputable) {
                        // 引數二e.loaded已傳輸的位元組
                        // 引數三e.total需傳輸的總位元組
                        var percenComplete = Math.ceil((e.loaded / e.total) * 100)
                        // console.log(percenComplete);
                        program.style.width = percenComplete + '%'
                        program.innerText = '%' + percenComplete 
                    }
                }
                // -----------------------------------
                // 2.上傳成功進度條變化
                xhr.upload.onload = () => {
                    program.className = ''
                    program.className = 'progress-bar progress-bar-success'
                }
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5.監聽事件
                xhr.onreadystatechange = () => {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {
                            document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {
                            console.log('上傳檔案失敗');
                        }
                    }
                }
            } else {
               return alert('請上傳檔案')
            }
        })
     </script>
</body>
</html>

6.

jQuery高階用法

用jq來實現檔案上傳

①定義ui結構和前面一樣

②驗證是否選擇檔案

③向formdata追加檔案

④使用jq發起上傳請求

⑤jq實現loading效果 兩個方法一檢測到任何ajax開始或失敗就會呼叫

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 1.定義UI結構 -->
    <form action="">
        <input type="file" name="file" id="">
    </form>
    <!-- 這裡出現了一點小問題 我在後面列印res始終打印不出來而且反正就想資料被清了一下思來想去才知道是我把button放在表單裡了所以一點選就會造成預設行為 -->
    <button type="submit">上傳圖片</button>
    <img style="display: none;" src="../../../../HTML/04-階段四 前後端互動/第四階段:前後端互動階段資料新/ajax課程資料/day3(7-12小節)/code/images/loading.gif" alt="">
    <script src="../day01/lib/jquery.js"></script>
    <script>
        // 5.這個方法是偵聽到所有的ajax請求就會開始執行
        $(document).ajaxStart(function() {
            $('img').show()
        })
        $(document).ajaxStop(function() {
            $('img').hide()
        })
        // 2.驗證是否選擇了檔案
        $('button').on('click', function() {
            // 這裡需要將jq物件轉為原生dom物件來使用files這個屬性
            var files = $('input')[0].files
            // console.log(files);
            if (files.length <= 0) {
                return alert('請選擇檔案')
            } else {
                // 3.向formdata追加檔案
                var fd = new FormData()
                fd.append('avatar', files[0])
                // 4.利用jq來發起上傳請求
                $.ajax({
          method: 'POST',
          url: 'http://www.liulongbin.top:3006/api/upload/avatar',
          data: fd,
          processData: false,
          contentType: false,
          success: function (res) {
            console.log(res)
          }
        })
            }
        })
    </script>
</body>
</html>

7.

axios

今天的最後一個內容,什麼事axios,專注於網路資料請求的庫,相比於原生xhr更簡單易用,相比於jq更輕量化

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./axios.js"></script>
</head>
<body>
    <button>發起get請求</button>
    <script>
        var btn = document.querySelector('button')
        /* btn.onclick = function() {
            var url = 'http://www.liulongbin.top:3006/api/get'
            var obj = {name : '張三', age : 29}
            axios.get(url, {params: obj}).then(function(res) {
                console.log(res);
            })
        } */
        btn.onclick = () => {
            axios({
                method : 'get',
                url : 'http://www.liulongbin.top:3006/api/get',
                params : {name : '張三', age : 29}
            }).then(res => console.log(res))
        }
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./axios.js"></script>
</head>
<body>
    <button>發起post請求</button>
    <script>
        /* document.querySelector('button').onclick =function() {
            var url = 'http://www.liulongbin.top:3006/api/post'
        var obj = {location : '重慶', address : '江北'}
        axios.post(url, {obj}).then(res => console.log(res))
        } */
        document.querySelector('button').onclick = () => {
            axios({
                method : 'post',
                url : 'http://www.liulongbin.top:3006/api/post',
                data : {name : '張三', age : 29}
            }).then(res => console.log(res))
        }
    </script>
</body>
</html>

<! DOCTYPE html >

< html lang = "en" >

< head >

< meta charset = "UTF-8" >

< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >

< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >

< title > Document </ title >

< link rel = "stylesheet" href = "../day01/lib/bootstrap.css" >

</ head >

< body >

<!-- 1.定義ui結構 -->

<!-- 1.1檔案選擇框 -->

< input type = "file" >

<!-- 1.2上傳按鈕 -->

< input type = "submit" value = "上傳檔案" >

<!-- 1.3img標籤 用來顯示上傳成功後的圖片 -->

< img src = "" alt = "" >

<!-- 進度條 -->

< div class = "progress" style = " width: 500px; " >

< div class = "progress-bar" role = "progressbar" aria-valuenow = "60" aria-valuemin = "0" aria-valuemax = "100" style = " width: 0%; " >

0%

</ div >

</ div >

< script >

//  2.驗證是否上傳了檔案

var uploadBtn = document . querySelector ( 'input:nth-of-type(2)' )

uploadBtn . addEventListener ( 'click' , function () {

// 2.1注意這裡這個。files它是一個數組存放的是檔案

let files = document . querySelector ( 'input:first-child' ). files

if ( files . length > 0 ) {

// 3.像formdata中追加檔案

var fd = new FormData ()

// avator為頭像假裝這裡是上傳的頭像

fd . append ( 'avatar' , files [ 0 ])

// 4.使用xhr發起上傳檔案請求

var xhr = new XMLHttpRequest ()

// --------------------------------

// 1.監聽事件

var program = document . querySelector ( '.progress-bar' )

xhr . upload . onprogress = e => {

// 2.引數一 e.lengthComputable是一個布林值,表示當前上傳的資源是否具有可計算的長度要有才能進去

if ( e . lengthComputable ) {

// 引數二e.loaded已傳輸的位元組

// 引數三e.total需傳輸的總位元組

var percenComplete = Math . ceil (( e . loaded / e . total ) * 100 )

// console.log(percenComplete);

program . style . width = percenComplete + '%'

program . innerText = '%' + percenComplete

}

}

// -----------------------------------

// 2.上傳成功進度條變化

xhr . upload . onload = () => {

program . className = ''

program . className = 'progress-bar progress-bar-success'

}

xhr . open ( 'post' , 'http://www.liulongbin.top:3006/api/upload/avatar' )

xhr . send ( fd )

// 5.監聽事件

xhr . onreadystatechange = () => {

if ( xhr . readyState == 4 && xhr . status == 200 ) {

// console.log(xhr.responseText);

let imgData = JSON . parse ( xhr . responseText )

if ( imgData . status == 200 ) {

document . querySelector ( 'img' ). src = 'http://www.liulongbin.top:3006' + imgData . url

} else {

console . log ( '上傳檔案失敗' );

}

}

}

} else {

return alert ( '請上傳檔案' )

}

})

</ script >

</ body >

</ html >