338 XMLHttpRequest 2.0

XMLHttpRequest是一個javascript內置對象,使得Javascript能夠進行異步的HTTP通訊。2008年2月,就提出了XMLHttpRequest Level 2 草案。javascript

老版本的XMLHttpRequest的缺點:php

// 1. 僅支持傳輸文本數據,沒法傳說二進制文件,好比圖片視頻等。
// 2. 傳輸數據時,沒有進度信息,只能提示完成與否。
// 3. 受到了"同源策略"的限制

新版本的功能:css

// 1. 能夠設置timeout 超時時間
// 2. 可使用formData對象管理表單數據
// 3. 能夠獲取數據傳輸的進度信息

1-設置超時
    xhr.timeout = 1000;
    xhr.ontimeout = function () {};
2-ajax上傳文件
    FormData對象
3-監聽上傳文件進度的功能
    xhr.upload.onprogress = function () {}

注意:咱們如今使用new XMLHttpRequest建立的對象就是2.0對象了,咱們以前學的是1.0的語法,如今學習一些2.0的新特性便可。html


timeout設置超時

xhr.timeout = 3000;//設置超時時間
xhr.ontimeout = function(){
  alert("請求超時");
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./form.css">
</head>
<body>
    <form >
        用戶名:
        <input type="text" >
        密碼:
        <input type="password" >
        <!-- <input type="submit" value="登陸" class="submit"> -->
        <!-- <button>我是button按鈕</button> -->
        <input type="button" value="登陸按鈕">
    </form>

    <script>
        // submit 按鈕,和雙標籤button按鈕,默認行爲都會刷新頁面,若是發生ajax請求,就須要阻止他們默認行爲;
        // 點擊按鈕,向後臺發送請求,
        document.querySelector('input[type="button"]').onclick = function () {
            // 1-建立一個XMLHttpRequest對象
            var xhr = new XMLHttpRequest();
            // 2-設置請求報文
            // 2-1請求行
            xhr.open('get', './timeout.php');
            xhr.timeout = 2000; // 設置超時
            xhr.ontimeout = function () {
                alert('網絡超時,請重試!');
            }
            // 2-2請求頭
            // 2-3請求主體
            xhr.send(null);


            //3-監聽服務器響應
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var r = xhr.responseText; 
                    console.log(r);                    
                }
            }
        }
    </script>
</body>
</html>

formData管理表單數據

formData對象相似於jquery的serialize方法,用於管理表單數據java

//使用特色: 
//1. 實例化一個formData對象, new formData(form); form就是表單元素
//4. formData對象能夠直接做爲 xhr.send(formData)的參數。注意此時數據是以二進制的形式進行傳輸。
//5. formData有一個append方法,能夠添加參數。formData.append("id", "1111");
//6. 這種方式只能以post形式傳遞,不須要設置請求頭,瀏覽器會自動爲咱們設置一個合適的請求頭。

代碼示例:jquery

//1. 使用formData必須發送post請求
    xhr.open("post", "02-formData.php");
    
//2. 獲取表單元素
var form = document.querySelector("#myForm");
//3. 建立form對象,能夠直接做爲send的參數。
var formData = new FormData(form);

//4. formData可使用append方法添加參數
formData.append("id", "1111");

//5. 發送,不須要指定請求頭,瀏覽器會自動選擇合適的請求頭
xhr.send(formData);

文件上傳

之前,文件上傳須要藉助表單進行上傳,可是表單上傳是同步的,也就是說文件上傳時,頁面須要提交和刷新,用戶體驗不友好,xhr2.0中的formData對象支持文件的異步上傳。ajax

var formData = new FormData();
//獲取上傳的文件,傳遞到後端
var file = document.getElementById("file").files[0];
formData.append("file", file);
xhr.send(formData);
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./form.css">
    <style>
        .info {
            width: 500px;
            min-height: 200px;
            border: 1px solid red;
            margin: 0 auto;
        }
        
        img {
            width: 100%;
        }
    </style>
</head>

<body>
    <form>
        用戶名:
        <input type="text" name="username"> 密碼:
        <input type="password" name="password"> 頭像:
        <input type="file" name="photo">
        <input type="button" value="註冊" class="btn">
    </form>

    <div class="info"></div>

    <script>
        // 點擊按鈕,獲取表單是數據和圖片,使用ajax發送給服務器
        // jquery的serialize表單序列化:(1)是jquery的方法;(2)只能序列化表單基本數據,文件不行
        // xhr2.0中新增了一個FormData對象,用於管理表單數據和文件
        // 注意點:
        //  一、FormData要求 必須使用post方式進行提交 
        //  二、FormData不須要手動設置請求頭,瀏覽器會自動設置一個合適請求頭
        //  FormData 使用二進制的形參進行傳遞
        document.querySelector('.btn').onclick = function() {
                var form = document.querySelector('form'); //獲取表單數據
                let fd = new FormData(form)
                var xhr = new XMLHttpRequest(); //使用ajax向後臺發送請求
                xhr.open('post', './02-formData.php'); //請求報文
                xhr.send(fd); // 只需發送FormData實例便可

                //監聽
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        console.log(xhr.responseText);
                        var r = xhr.responseText;
                        document.querySelector('.info').innerHTML = r;
                    }
                }
            }
            //順豐   包子 饅頭 
            //中國郵政: 寄一切  分子 原子 01010101 010101010100
    </script>
</body>

</html>
<?php 
    // echo '<pre>';
    // print_r($_POST);
    // echo '</pre>';

    // echo '<pre>';
    // print_r($_FILES);
    // echo '</pre>';

    //轉移文件位置
    move_uploaded_file($_FILES['photo']['tmp_name'], './test.png');

    echo '<img src="./test.png"/>';
    // echo '<img src="E:/圖片/桌面圖片2/康寧/康寧1.jpg>';
?>

顯示文件進度信息

xhr2.0還支持獲取上傳文件的進度信息,所以咱們能夠根據進度信息能夠實時的顯示文件的上傳進度。後端

1. 須要註冊 xhr.upload.onprogress = function(e){} 事件,用於監聽文件上傳的進度.注意:須要在send以前註冊。
2. 上傳的進度信息會存儲事件對象e中
3. e.loaded表示已上傳的大小   e.total表示整個文件的大小

代碼參考:瀏覽器

xhr.upload.onprogress = function (e) {
  inner.style.width = (e.loaded/e.total*100).toFixed(2)+"%";
  span.innerHTML = (e.loaded/e.total*100).toFixed(2)+"%";
}

xhr.send(formData);

若是上傳文件超過8M,php會報錯,須要進行設置,容許php上傳大文件。服務器

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./form.css">
    <style>
        .out {
            position: relative;
            width: 800px;
            height: 20px;
            border: 1px solid red;
            margin: 0 auto;
            overflow: hidden;
            border-radius: 10px;
        }
        
        .in {
            width: 5%;
            height: 100%;
            background-color: hotpink;
        }
        
        span {
            position: absolute;
            left: 48%;
            top: 0;
        }
    </style>
</head>

<body>
    <form>
        用戶名:
        <input type="text" name="username"> 密碼:
        <input type="password" name="password"> 頭像:
        <input type="file" name="photo">
        <input type="button" value="註冊" class="btn">
    </form>


    <div class="out">
        <div class="in"></div>
        <span>0</span>
    </div>

    <script>
        document.querySelector('.btn').onclick = function() {
            //獲取表單數據
            var fd = new FormData(document.querySelector('form'));
            var num = 100;
            fd.append('num', 100);
            fd.append('num1', 100);
            var xhr = new XMLHttpRequest(); //經過ajax來發送
            xhr.open('post', './03-progress.php'); //請求報文

            // 註冊監聽文件上傳事件
            xhr.upload.onprogress = function(e) {
                // e 事件對象, 存儲的是當前事件相關信息
                // 獲取文件上傳的進度
                // e.total  文件總大小
                // e.loaded 已經上傳大小
                var value = e.loaded / e.total;
                console.log(value);
                //0.5 --> 50%  0.5* 100 + '%';
                //把進度設置給進度條
                document.querySelector('.in').style.width = value * 100 + '%';
                document.querySelector('span').innerText = parseInt(value * 100) + '%';
            }

            xhr.send(fd);

            //監聽
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    console.log(xhr.responseText);
                }
            }
        }
    </script>
</body>

</html>
<?php 
    echo 'hehe';
?>
相關文章
相關標籤/搜索