zoukankan      html  css  js  c++  java
  • 338 XMLHttpRequest 2.0

    XMLHttpRequest是一个javascript内置对象,使得Javascript可以进行异步的HTTP通信。2008年2月,就提出了XMLHttpRequest Level 2 草案。

    老版本的XMLHttpRequest的缺点:

    // 1. 仅支持传输文本数据,无法传说二进制文件,比如图片视频等。
    // 2. 传输数据时,没有进度信息,只能提示完成与否。
    // 3. 受到了"同源策略"的限制
    

    新版本的功能:

    // 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的新特性即可。


    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方法,用于管理表单数据

    //使用特点: 
    //1. 实例化一个formData对象, new formData(form); form就是表单元素
    //4. formData对象可以直接作为 xhr.send(formData)的参数。注意此时数据是以二进制的形式进行传输。
    //5. formData有一个append方法,可以添加参数。formData.append("id", "1111");
    //6. 这种方式只能以post形式传递,不需要设置请求头,浏览器会自动为我们设置一个合适的请求头。
    

    代码示例:

    //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对象支持文件的异步上传。

    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 {
                 500px;
                min-height: 200px;
                border: 1px solid red;
                margin: 0 auto;
            }
            
            img {
                 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对象,用于管理表单数据和文件
            // 注意点:
            //  1、FormData要求 必须使用post方式进行提交 
            //  2、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;
                 800px;
                height: 20px;
                border: 1px solid red;
                margin: 0 auto;
                overflow: hidden;
                border-radius: 10px;
            }
            
            .in {
                 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';
    ?>
    
  • 相关阅读:
    移动端rem适配
    extern 关键字
    腾讯2014校园招聘软件开发类笔试试题
    堆,栈,堆栈
    转:对TCP/IP网络协议的深入浅出归纳
    转:程序员面试笔试宝典学习记录(一)
    求素数
    [C++]访问控制与继承(public,protect,private) 有时间再整理!!!
    面向对象的static关键字(类中的static关键字)
    腾讯校园招聘会笔试题2011.10.15
  • 原文地址:https://www.cnblogs.com/jianjie/p/12383800.html
Copyright © 2011-2022 走看看