AJAX

AJAX

关于ajax和异步

什么是ajax?

  1. 交互式网站开发技术
  2. 实现动态更新(局部)的内容

优点:

  1. 提升浏览器的加载速度
  2. 实现了局部刷新
  3. 表单验证(增强用户体验)

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术

本质:是在HTTP协议的基础上以异步的方式通过XMLHttpRequest对象与服务器进行通信。

作用:可以在页面不刷新的情况下,请求服务器,局部更新页面的数据;

1.ajax编程

1.1异步(Asynchronous)

指某段程序执行时不会阻塞其它程序执行,其表现形式为程序的执行顺序不依赖程序本身的书写顺序,相反则为同步。

其优势在于不阻塞程序的执行,从而提升整体执行效率。

同步:同一时刻只能做一件事,上一步完成才能开始下一步

异步:同时做多件事,效率更高

XMLHttpRequest可以以异步方式的处理程序。

1.2XMLHttpRequest

前端的register.html文件

<form>     
    <span id="msg">aaaspan>  
    用户名:<input type="text" name="username" id="username">
    昵称:<input type="text" name="nickname" >
    密码: <input type="password" name="password" >   
    <input type="submit" value="注册">
form>


<div class="showmsg">div>

前端基于http发送的一个异步请求

前端的get请求(重要)

<script>
        document.querySelector("#username").onblur = function(){
            // 1.获取用户数据
            var name = this.value;

            // 2,让异步对象发送请求
            // 2.1 创建异步对象
            var xhr = new XMLHttpRequest();
            // 2.2 设置 请求行 open(请求方式,请求url):
                // get请求如果有参数就需要在url后面拼接参数,
            xhr.open("get","validate.php?username="+name);
            // 2.3 设置 请求头 setRequestHeader('key':'value')
                // get方式不需要设置请求头
            // 2.4 设置 请求体:发送请求  send(参数:key=value&key=value)
                // 对于 get请求不需要在这个位置来传递参数
            xhr.send(null);

            // 响应报文:
            // 报文行:响应状态码 响应状态信息  200 ok
            // 报文头:服务器返回给客户端的一些额外信息  
            // 报文体:服务器返回给客户端的数据 responseText:普通字符串  responseXML:符合xml格式的字符串
            // xhr.status:可以获取当前服务器的响应状态  200 》成功
            console.log(xhr.status);
            // 一个真正成功的响应应该两个方面:1.服务器成功响应  2.数据已经回到客户端并且可以使用了
            // 监听异步对象的响应状态 readystate
            // 0:创建了异步对象,但是还没有真正的去发送请求
            // 1.调用了send方法,正在发送请求
            // 2.send方法执行完毕了,已经收到服务器的响应内容--原始内容,还不可以使用
            // 3.正在解析数据
            // 4.响应内容解析完毕,可以使用了
            xhr.onreadystatechange = function(){
                //等待浏览器返回成功并且解析完毕
                if(xhr.status == 200 && xhr.readyState == 4){
                    console.log(xhr.responseText);
                    console.log("-----------");
                    document.querySelector(".showmsg").innerHTML = xhr.responseText;;
                }
            }
        };
    </script>

前端的post请求(重要)

<script>
        document.querySelector("#username").onblur = function(){
            // 1.获取用户数据
            var name = this.value;
            // 2. 让异步对象发送post请求
            // 2.1 创建异步对象
            var xhr = new XMLHttpRequest();
            // 2.2 设置请求行 open(请求方式,请求url)
                // 2.post请求不需要拼接参数
            xhr.open("post","validate.php");
            // 2.3 设置请求头:setRequestHeader()
                // 2.post需要设置请求头:Content-Type:application/x-www-form-urlencoded
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    		//.如果没有设置,参数无法正确的传递到服务器(本质上说,如果没有参数,也不一定需要设置,不会影响请求的发送)
            // 2.4 设置请求体 send()
                // 2.post的参数在这个函数中设置(如果有参数)
            xhr.send("username="+name);

            // 3.让异步对象接收服务器的响应数据
            // 一个成功的响应有两个条件:1.服务器成功响应了  2.异步对象的响应状态为4(数据解析完毕可以使用了)
            // 当异步对象的响应状态发生改变的时候,会触发一个事件:onreadystatechange
            xhr.onreadystatechange = function(){
                // 判断服务器是否响应      判断异步对象的响应状态
                if(xhr.status == 200 && xhr.readyState == 4){
                    document.querySelector(".showmsg").innerHTML = xhr.responseText;
                }
            }
        };
    </script>

处理后端的php文件

 
    header('content-type:text/html;charset=utf-8');
    if($_SERVER['REQUEST_METHOD'] == 'POST'){
        //获取用户名
        $name=$_POST['username'];
        //判断数据库中是否已有这个用户名
        $names=['jack','rose','tom','lili'];
        //有则注册失败,否则成功
        if(in_array($name,$names)){
            $str = '这个名字太火了,换一个吧!';
            echo $str;
        }else{
            $str = '恭喜,名字可用!';
            echo $str;
        }
    }
?>

API 详解

xhr.open() 发起请求,可以是get、post方式

xhr.setRequestHeader() 设置请求头

xhr.send() 发送请求主体get方式使用xhr.send(null)

xhr.onreadystatechange = function () {} 监听响应状态

readstate 属性有五个状态:

  • xhr.readyState = 0时,(未初始化)还没有调用send()方法
  • xhr.readyState = 1时,(载入)已调用send()方法,正在发送请求
  • xhr.readyState = 2时,(载入完成)send()方法执行完成,已经接收到全部响应内容
  • xhr.readyState = 3时,(交互)正在解析响应内容
  • xhr.readyState = 4时,(完成)响应内容解析完成,可以在客户端调用了

不用记忆状态,只需要了解有状态变化这个概念

xhr.status表示响应码,如200

xhr.statusText表示响应信息,如OK

xhr.getAllResponseHeaders() 获取全部响应头信息

xhr.getResponseHeader(‘key’) 获取指定头信息

xhr.responseText、xhr.responseXML都表示响应主体

注GET和POST请求方式的差异(面试题)

1、GET没有请求主体,使用xhr.send(null)

2、GET可以通过在请求URL上添加请求参数

3、POST可以通过xhr.send(‘name=itcast&age=10’)

4、POST需要设置

5、GET大小限制约4K,POST则没有限制

1.3 使用异步对象发送读取JSON文件

JSON格式的数据和特点

描述数据的一种格式

[
    {
       "src":"./images/nav_1.png" ,
       "text":"京东超市"
    },
    {
        "src":"./images/nav_2.png" ,
        "text":"全球购物"
     },
     {
        "src":"./images/nav_3.png" ,
        "text":"京东市场"
     }
]

规则和特点

关于json的描述
1,一组花括号表示一个对象,一个对象通过键值对写入一堆相关数据
2,一组方括号表示一个数组,多组对象通过数组的方式装载
3,对象的所有属性都必须加上双引号,值没有undefined
4,文件后缀名为.json,json格式的数据内不允许写注释

操作json的方法

前端(Javascript)操作json的方式
JSON.parse(json字符串) 将json格式的字符串转换为数组或者对象
JSON.stringify(对象或者数组) 将字面量对象或者数组转换为json格式的字符串
php操作json的方式
json_decode(json字符串) 将json格式的字符串转换为php的数组或者对象
json_encode(关联数组) 将php的数组转换为json字符串

关于json的操作

<script>
        // 让异步对象发送异步请求
        // 1.创建对象
        var xhr = new XMLHttpRequest();
        // 2.设置请求行
        xhr.open("get", "./server/nav-json.php");
        // 3.设置请求头:get不需要设置
        // 3.设置请求体
        xhr.send();

        // 让异步对象接收服务器响应数据:一个成功的响应包含两个条件:1.服务器成功响应了  2.数据解析完毕可以使用了
        xhr.onreadystatechange = function() {
            if (xhr.status == 200 && xhr.readyState == 4) {
                var result = xhr.responseText;
                var data = JSON.parse(result);
                var html = "";
                for (var i = 0; i < data.length; i++) {
                    html += "
  • "; html += ''; html += '+ data[i].src + '" alt="">'; html += '

    ' + data[i].text + '

    '
    ; html += '
    '; html += '
  • '
    ; } // 将生成的页面结构添加到dom元素中 document.querySelector("ul").innerHTML = html; } } </script>

    后端处理php文件的代码

    
        echo file_get_contents("../data/nav.json");
    ?>
    

    1.4封装AJAX工具函数

    // type:请求方式
    // url:请求url
    // data:传递给服务器的参数
    // callback:客户端的动态结构的渲染方式
    
    // 下面的封装方式的缺点:
    // 1.参数数量固定:用户在调用的时候必须传入四个参数
    // 2.参数的顺序固定:用户在调用的时候必须按照顺序进行参数的传递
    // 3.不方便后期封装功能的扩展与修改
    // function ajax(type,url,data,callback){}
    
    // 解决方式:通过传入对象的方式来设置参数
    // option是一个对象,它里面包含着相关的属性:如type,url,data,callback
    // 不方便后期功能的添加与扩展
    // 会造成当前文件中存在着大量的全局变量,会造成全局变量污染
    // function ajax(option){}
    // function get(option){}
    // function post(option){}
    // 建议的封装方式:
    var $ = {
        // 将{"name":"jack","age":20} 的参数要转换为 ?name=jack&age=20
        getpa:function(data){
            if(data && typeof data == "object"){
                var str = "?";
                for(var key in data){
                    str = str + key + "=" + data[key] + "&";
                }
                str = str.substr(0,str.length-1);
            }
            return str;
        },
        // option.type:请求方式
        // option.url:请求的url
        // option.data:当前请求所传递的参数:规定参数必须是以对象的形式传递{"name":"jack","age":20}
        // option.success:渲染方式
        ajax:function(option){
            // 接收用户参数进行相应处理
            var type = option.type || 'get';
            // location.href 可以获取当前文件的路径 
            var url = option.url || location.href;
            // 接收参数:在js中最方便收集的数据类型为对象,所以我们就规定传递的参数必须是对象
            var data = this.getpa(option.data) || "";
            // 响应成功之后的回调
            var success = option.success;
    
            // 创建异步对象
            var xhr = new XMLHttpRequest();
    
            // 让异步对象发送请求
            // 请求行
            if(type == "get"){
                // 拼接参数
                url += data;
                data = null;
            }
            xhr.open(type,url);
            // 请求头
            if(type == "post"){
                xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            }
            // 请求体
            xhr.send(data);
    
            // 让异步对象接收响应
            xhr.onreadystatechange = function(){
                // 一个成功的响应有两个条件:1.服务器成功响应 2.数据解析完毕可以使用
                if(xhr.status == 200 && xhr.readyState == 4){
                    // 接收响应的返回值
                    // responseText   responseXML
                    var rh = xhr.getResponseHeader("Content-Type");
                    // 判断
                    if(rh.indexOf("xml") != -1){
                        var result = xhr.responseXML;
                    }
                    else if(rh.lastIndexOf("json") != -1){
                        var result = JSON.parse(xhr.responseText);
                    }else{
                        var result = xhr.responseText;
                    }
    
                    // 接收数据之后,调用回调函数
                    success && success(result)
                }
            }
        },
        get:function(option){
    
        },
        post:function(){
    
        }
    }
    

    2.jQuery中的ajax

    $.ajax({这里传入一个字面量对象}) 参数说明
    url 接口地址
    type 请求方式
    timeout 请求超时,单位是毫秒
    dataType 服务器返回的格式, json / xml / jsonp
    data 发送请求的数据
    beforeSend: fucntion() { …code } 请求发起前的调用
    success: fucntion() { …code } 成功响应后的调用
    error: fucntion() { …code } 错误响应时的调用,e参数为报错信息
    complete: fucntion() { …code } 响应完成时的调用
    async true/false(默认true,异步;false,同步)

    完整的jQuery调用(重要)

    $.ajax({
        type: 'post',
        url: './server/nav-json.php',
        data: {}, //请求需要传递的参数
        // 设置请求超时:单位为毫秒,如果服务器的响应时间超过指定的时候,请求失败
        timeout: 3000,
        dataType:'json', // 设置响应数据的格式  xml json text html script jsonp
        // 发送请求之前的回调
        beforeSend:function(){
            // 在这个回调函数中,如果return false,那么本次请求会中止
            // return false;
        },
        success: function() {
            //请求成功之后的回调
        }, 
        // 请求失败之后的回调
        error:function(e){
            if(e.statusText == "timeout"){
            	alert("请求超时,请重试");
            }
        },
        // 无论请求是成功还是失败都会执行的回调
        complete:function(){
        	console.log('实现一些全局成员的释放,或者页面状态的重置....');
        }
    });
    

    1.jQuery中ajax的其他用法

    1.1$.get()的使用

    本质上只能发送get请求

    $.get(url, data, success, datatype) 说明
    url 所请求的url
    data 请求所传递的数据
    success: function() { …code } 成功之后的回调
    datatype: 需要返回的数据类型
    $.get("./server/nav-json.php", function() {
      	// 成功回调之后的函数
    }, "json")
    

    1.2$.post()的使用

    参数一致,用法一直,目的一致

    ​ 代码略.

    3.模板引擎

    Js插件: template_native.js

    作用:渲染数据时 代替 拼接字符串的操作

    如果数据是一个对象,就直接传入对象

    如果数据是一个数组,就包装对对象再传递

    因为在模板中只能使用当前传入的对象的属性,它会根据属性自动的去获取对应的值来使用

    3.1原生语法(遍历用for)

    1.单个数据的结构生成

    <script type="text/template" id="navTemp">
        <li>
            <a href="#">
                <img src="<%=src%>" alt="">
                <p><%=text%></p>
            </a>
        </li>
    </script>
    <script src="./js/template-native.js"></script>
    <script>
    var obj = {
           "src":"./images/nav_1.png" ,
           "text":"京东超市"
        };
        // 调用模板引擎中的函数,返回值为替换之后的动态结构
        // var html = template(模板id,数据(对象));
        var html = template("navTemp",obj);
        console.log(html);
        document.querySelector("ul").innerHTML = html;
    </script>
    

    **2.多个数据的动态结构生成 **

    <script type="text/template" id="navTemp">
            <% for(var i=0;i<items.length;i++){ %>
                <li>
                    <a href="#">
                    <img src="<%=items[i].src%>" alt="">
                    <p><%=items[i].text%></p>
                </a>
                </li>
                <% } %>
        </script>
    <script src="./js/template-native.js"></script>
    <script>
    var arr = [{
                "src": "./images/nav_1.png",
                "text": "京东超市"
            }, {
                "src": "./images/nav_2.png",
                "text": "全球购物"
            }, {
                "src": "./images/nav_3.png",
                "text": "京东市场"
            }];
            var html = template("navTemp", {
                "items": arr
            });
            console.log(html);
            document.querySelector("ul").innerHTML = html;
    </script>
    

    3.2标准语法(遍历用each as)

    <script type="text/template" id="musicTemp">
    		{{each items as value index}}
    			{{if index == 0}}
    				<tr bgcolor='red'>
    			{{else if index == 1}}
    				<tr bgcolor='green'>
    			{{else}}
    				<tr bgcolor='blue'>
    			{{/if}}
    				<td>{{items[index].title}}</td>
    				<td>{{value.singer}}</td>
    				<td>{{value.album}}</td>
    				<td>
    					<audio src="{{value.src}}" controls></audio>
    				</td>
    				<td>
    					<a href="./edit.php?id={{value.id}}" class="btn btn-primary">编辑</a>
    					<a href="./delete.php?id={{value.id}}" class="btn btn-danger">删除</a>
    				</td>
    			</tr>
    		{{/each}}
    	</script>
    	<script src="./js/jquery.min.js"></script>
    	<script src="./js/template.js"></script>
    	<script>
    		// 发送ajax请求
    		$.ajax({
    			url: "./music.php",
    			dataType: 'json',
    			success: function (result) {
    				// 调用模板引擎动态生成页面结构
    				// 如果参数是对象是直接传入对象
    				// 如果参数是数组,就包装为对象
    				var html = template("musicTemp",{"items":result});
    				$("tbody").html(html);
    			}
    		});
    	</script>
    

    4.同源&跨域

    同源策略是浏览器的一种安全策略,所谓同源是指,域名,协议,端口完全相同。

    JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。那什么是跨域呢,简单地理解就是因为JavaScript同源策略的限制,a.com域名下的js无法操作b.com或是c.a.com域名下的对象。
    当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。

    注意跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致

    例如http://www.example.com/

    http://api.example.com/detail.html 不同源 域名不同
    https//www.example.com/detail.html 不同源 协议不同
    http://www.example.com:8080/detail.html 不同源 端口不同
    http://api.example.com:8080/detail.html 不同源 域名、端口不同
    https://api.example.com/detail.html 不同源 协议、域名不同
    https://www.example.com:8080/detail.html 不同源 端口、协议不同
    http://www.example.com/detail/index.html 同源 只是目录不同
    说明
    第一:如果是协议和端口造成的跨域问题“前端”是无能为力的
    第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会根据域名对应的IP地址是否相同来判断。“URL的首部”可以理解为“协议, 域名和端口必须匹配”

    所有跨域都必须经信息提供方允许, 如果未经允许即可获取, 那是浏览器同源策略出现漏洞

    实现跨域

    1.服务器端设置CORS跨域(cross-origin resource sharing 跨域资源共享)

    
    	// 设置跨域请求
    	//header("Access-Control-Allow-Origin:*"); // * 允许代表所有域来请求
    	header("Access-Control-Allow-Origin:http://day09.com");
    
    	echo file_get_contens("nav.json");
    ?>
    

    2.jsonp的实现原理

    页面中有几个标签允许跨域请求资源 a链接的hrefimg的srclink的hrefscript的src

    1.主要是利用了script标签的天然的跨域特性来发送请求

    2.它的实现方式:在发送请求的时候传递一个函数名称给后台,后台返回数据的时候会返回这个函数的调用形式,并且在()中拼接参数

    3.ajax和jsonp的本质不一样。ajax的核心是通过XMLHttpRequest来发送请求,而jsonp是通过script标签来实现请求的发送

    实现方式

    1. 先定义一个函数,然后动态创建script src去请求资源
    2. 在请求地址后面要加参数(参数名=函数名)
    3. 后台拿到函数名,再以函数名调用的形式返回
    4. 拿到数据直接调用
    • 前端开启跨域请求(dataType:“jsonp”)
    <script>
        $.ajax({
            type:'get',
            // url:'getnav.php',
            url:'http://day8.com/getnav.php',
            // dataType:'json',
            // 开启跨域请求
            dataType:"jsonp",
            success:function(result){
                console.log("有没有调用、");
                var html = template("navTemp",{"items":result});
                document.querySelector("ul").innerHTML = html;
            }
        });
    </script>
    
    • 后端进行拼接(拼接字符串)
    
        //这就是请求时所传递过来的函数名称
        $callback = $_GET["callback"];
        //读取数据
        $data = file_get_contents("nav.json");
        //返回调用函数的形式,只不过在这个形式中要传递前台需要的数据
        echo $callback.'('.$data.')';
    ?>
    

    获取天气案列

    <body>
        <table border="1">
            <thead>
                <tr>   
                    <th>date</th>
                    <th>dayPictureUrl</th>
                    <th>nightPictureUrl</th>
                    <th>temperature</th>
                    <th>weather</th>
                    <th>wind</th>
                </tr>
            </thead>
            <tbody>
                <!-- <tr>
                    <td>周六 03月31日 (实时:12)</td>
                    <td><img src="http://api.map.baidu.com/images/weather/day/yin.png" alt=""></td>
                    <td><img src="http://api.map.baidu.com/images/weather/night/duoyun.png" alt=""></td>
                    <td>17 ~ 8</td>
                    <td>阴转多云</td>
                    <td>南风微风</td>
                </tr> -->
            </tbody>
        </table>
        <script type="text/template" id="weatherTemp">
            <% for(var i=0;i<items.length;i++){ %>
                <tr>
                    <td><%=items[i].date%></td>
                    <td><img src="<%=items[i].dayPictureUrl%>" alt=""></td>
                    <td><img src="<%=items[i].nightPictureUrl%>" alt=""></td>
                    <td><%=items[i].temperature%></td>
                    <td><%=items[i].weather%></td>
                    <td><%=items[i].wind%></td>
                </tr>
            <% }%>
        </script>
        <script src="./js/jquery.min.js"></script>
        <script src="./js/template-native.js"></script>
        <script>
            $.ajax({
                type:'post',
                url:"http://api.map.baidu.com/telematics/v3/weather",
                data:{
                    "ak":"zVo5SStav7IUiVON0kuCogecm87lonOj",
                    "location":"北京",
                    "output":'json'
                },
                dataType:'jsonp',
                // jsonpCallback:function(){}
                success:function(result){
                    console.log(result);
                    var html = template("weatherTemp",{"items":result.results[0].weather_data});
                    document.querySelector("tbody").innerHTML = html;
                }
            });
        </script>
    </body>
    

    5.XMLHttpRequest2.0

    5.1 timeout(延迟)

    timeout代表延迟,可以当作属性设置延迟,单位为毫秒,也可以作为事件

    a) 设置超时 xhr.timeout

    b) 监听超时事件 xhr.ontimeout = function () {// code}

    <body>
        <button> 发送请求</button>
        <!-- <script src="../01-cross-origin/js/jquery.min.js"></script> -->
        <script>
            document.querySelector("button").onclick = function() {
                var xhr = new XMLHttpRequest();
    
                // 设置请求行
                xhr.open("get","01-timeout.php");
                // 设置请求头:get不需要设置
                // 设置请求体
                xhr.send(null);
    
                // 设置超时
                xhr.timeout = 2000;
                xhr.ontimeout = function(e){
                    console.log(e);
                }
    
                // 接收响应
                xhr.onreadystatechange = function(){
                    if(xhr.status == 200 && xhr.readyState == 4){
                        alert(xhr.responseText);
                    }
                }
                // $.ajax({
                //     type: "get",
                //     url: "01-timeout.php",
                //     timeout: 3000,
                //     success: function(data) {
                //         console.log(data);
                //     },
                //     error: function() {
                //         console.log('超时了');
                //     }
                // })
            }
        </script>
    </body>
    

    5.2 FormData(获取表单元素)

    form内表单元素的name属性是必须的,但是不需要再一个个获取了

    formdata.append(“address”,“传智播客”);可以自由的追加参数

    a) 提供了一个新的内建对象,可用于管理表单数据

    b) 首先要获取一个表单元素form

    c) 然后在实例化时 new FormData(form),将表单元素form传进去

    d) 会返回一个对象,此对象可以直接做为xhr.send(formData)的参数

    e) 此时我们的数据就是以二进制形式传递了(不需要设置请求头)

    f) 注意我们这里只能以post形式传递,浏览器会自动为我们设置一个合适的请求头

    <body>
        <form id="form1">
            用户名:<input type="text" name="username"> 密码:
            <input type="password" name="password"> 电话:
            <input type="text" name="phone">
            <input type="button" value="发送ajax请求" id="sub">
        </form>
        <div></div>
        <img src="" alt="" width="80">
        <script>
            document.querySelector("#sub").onclick = function() {
                var xhr = new XMLHttpRequest();
    
                xhr.open("post","02-formData.php");
                // 1.手动拼接
                // 2.如果是jq,那么就可以使用表单序列化方法
                // 3.现在在XMLHttpRequest2.0   ,我们可以使用FormData来收集表单数据
    
                // 1.获取表单
                var myform = document.querySelector("#form1");
                // 2.将表单做为参数传递,在创建formData对象的时候
                var formdata = new FormData(myform);
    
                // 特点之一:可以自由的追加参数
                formdata.append("address","传智播客");
                // 3.生成的formData对象就可以直接做为异步对象的参数传递
                xhr.send(formdata);
    
                xhr.onreadystatechange = function(){
                    if(xhr.status == 200 && xhr.readyState == 4){
                        console.log(xhr.responseText);
                    }
                }
                
            }
        </script>
    </body>
    

    传统获取表单元素方法

    前端

    <body>
        <form id="form1">
            用户名:<input type="text" name="username" class="username"> 密码:
            <input type="password" name="password" class="pass"> 电话:
            <input type="text" name="phone" class="phone">
            <input type="button" value="发送ajax请求" id="sub">
        </form>
        <div></div>
        <img src="" alt="" width="80">
        <script>
            document.querySelector("#sub").onclick = function() {
                var xhr = new XMLHttpRequest();
                xhr.open("post", "02-formData.php");
                xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                var username = document.querySelector(".username").value;
                var password = document.querySelector(".pass").value;
                var phone = document.querySelector(".phone").value;
                var data = "username="+username+"&"+"password="+password+"&"+"phone="+phone;
                xhr.send(data);
                xhr.onreadystatechange = function() {
                    if (xhr.status == 200 && xhr.readyState == 4) {
                        console.log(data);
                    }
                }
    
            }
        </script>
    </body>
    

    5.3 上传文件的POST请求

    **注意:**这里设置了请求头的话,数据无法传递

    前端

    <body>
        <form id="form1">
            用户名:<input type="text" name="username"> 密码:
            <input type="password" name="password"> 头像:
            <input type="file" name="myfile" id="pic">
            <input type="button" value="发送ajax请求" id="sub">
        </form>
        <div class="progress">
            <div class="in"></div>
            <span>0%</span>
        </div>
        <img src="" alt="" class="photo">
        <script>
            document.querySelector("#sub").onclick = function() {
                var xhr = new XMLHttpRequest();
                xhr.open("post", "03-uploadFile.php");
                // 我想自己来设置一个请求头,看行不行--注意了,如果人为了设置了请求头,那么文件数据无法正确的传递
                // xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    
                var myform = document.querySelector("#form1");
                var formData = new FormData(myform);
    
                // 监听文件上传的进度:这个监听必须在send之前来设置
                xhr.upload.onprogress = function(e) {
                    var current = e.loaded; //上传了多少
                    var total = e.total; //总共
                    var percent = current / total * 100 + "%";
                    document.querySelector(".in").style.width = percent;
                    document.querySelector("span").innerHTML = Math.floor(current / total * 100) + "%";
    
                }
                xhr.send(formData);
                xhr.onreadystatechange = function() {
                    if (xhr.status == 200 && xhr.readyState == 4) {
                        // console.log(xhr.responseText);
                        var data = JSON.parse(xhr.responseText);
                        document.querySelector(".photo").src = data["src"];
    
                    }
                }
            }
        </script>
    </body>
    

    后端

    
        move_uploaded_file($_FILES['myfile']['tmp_name'],"./upload/".$_FILES["myfile"]["name"]);
        $data = Array("src"=>"./upload/".$_FILES["myfile"]["name"]);
        echo json_encode($data);
    ?>
    

    5.4 onprogress监听文件上传的进度

    注意:这段代码一定要在send方法之前

    // 监听文件上传的进度:这个监听必须在send之前来设置
    xhr.upload.onprogress = function(e) {
       var current = e.loaded; //上传了多少
       var total = e.total; //总共
       var percent = current / total * 100 + "%";
       document.querySelector(".in").style.width = percent;
       document.querySelector("span").innerHTML = Math.floor(current / total * 100) + "%";
            }
    xhr.send(formData);
    

    你可能感兴趣的:(前端)