【前端总览】Ajax 复习

Ajax预备知识

post和get区别

get

(1)会将上传的内容写在url后面,安全性不高

(2)有最大上传大小限制

post

(1)上传的内容在包头部,url上看不到

(2)没有最大上传大小限制

应用场景

通常小文件,不考虑安全性的时候用get方法。

大文件和需要保密的时候用post

使用服务器实现简单的文件上传(post方法)

(服务器使用wamp)

  • 注意事项

(1)上传文件要用post方法(可能比较大,get限制大小,且更安全)

(2)表单要指定enctype为二进制格式,否则无法读取,只能读到文件名

(3)后端php使用$_FILES[name]获取该文件字典,name为input的name

(4)PHP中会把文件暂时放在一个临时目录,但无法直接从这里取到文件,因为这里的文件不进行处理就会被快速删除,需要把这里的文件拿出来存到自己指定的位置,用到move_uploaded_file方法

(5)路径不要带中文,否则会报错。

  • 简单上传
html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form action="upload1.php" method="post">
      <input type="file" name="upload" id="upFIle" />
      <input type="submit" value="upload" />
    </form>
  </body>
</html>
php
<?php
    print_r($_POST);
?>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4sYSJqg4-1603972484193)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20201023154213483.png)]

  • 保存上传的文件
注意 表单要用二进制格式才能读取到上传的文件(enctype)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form action="upload1.php" method="post" enctype="multipart/form-data">
      <input type="file" name="upload" id="upFIle" />
      <input type="submit" value="upload" />
    </form>
  </body>
</html>
<?php

// 1.获取上传文件对应的字典(key-value格式)

    $fileInfo=$_FILES['upload'];
    // print_r($fileInfo);

// 2.获取文件名

    $fileName=$fileInfo['name'];

// 3.获取文件的临时保存路径
    $filePath=$fileInfo['tmp_name'];

// 4.保存文件
	//第一个参数上传上来的文件的暂时路径
	//第二个参数要保存的路径(包括文件名)
    move_uploaded_file($filePath,'./source/'.$fileName);
?>

大型文件上传

  • 虽然post方法上传理论上没有大小限制,但web服务器对上传的文件大小有限制,需要进行修改

  • 修改php.ini

(1)位置:wamp目录–bin–apache–bin

(2)要修改的位置:

1.file_uploads=On	默认应该就是On,不用改

2.upload_max_filesize=2048M 上传文件最大大小

3.post_maxsize=2048M	post方法上传最大大小

4.max_execution_time=30000 脚本执行的最长时间 秒

5.max_input_time=3000	接收提交数据的时间限制 秒

6.memory_limit=2048M	内存消耗限制

Ajax基本概念

  • 使用ajax,可以在不更新整个网页的前提下进行交互。比如百度搜索框下弹出的可能内容

在这里插入图片描述

  • ajax是基于JS的前端技术

Ajax-GET方法

GET方法基本使用
  • 使用步骤
1.创建xmlhttp异步对象
2.设置请求方式和地址
3.发送请求
4.监听状态,进行处理
  • 具体代码

(1)php部分随便写

get1.php
<?php
    echo 'hello world ajax !'
?>

(2)在html页面中写JS脚本

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button>send message</button>

    <script>
      let btn = document.querySelector("button");
      btn.onclick = function (val) {
        // 1.创建异步对象
        let xmlhttp = new XMLHttpRequest();

        // 2.设置请求方式和地址
        xmlhttp.open("GET", "./get1.php", true);
        /*
                open的参数
                01 请求方式 GET / POST
                02 请求地址
                03 同步false/异步true   ajax固定异步,必须是true
            */

        // 3.发送请求
        xmlhttp.send();

        // 4.监听状态
        xmlhttp.onreadystatechange = function (val2) {
          // 5.进行处理
          // 5.1当消息传输完成时才进行处理
          if (xmlhttp.readyState === 4) {
            // 5.2判断消息是否正常传输,没有发生错误
            if (
              (xmlhttp.status >= 200 && xmlhttp.status < 300) ||
              xmlhttp.status === 304
            ) {
              // 5.3对成功状态进行处理
              console.log("传输完成!");
            } else {
              console.log("传输出错!");
            }
          }
        };
      };
    </script>
  </body>
</html>

(3)结果:

传输出错的结果

在这里插入图片描述

正确的结果

在这里插入图片描述

  • 状态码总结

(1)readyState

0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪

(2)state

[200,300)都是成功
304 是访问了本地缓存,也算成功
404 是未找到页面
  • 获得服务器返回的数据

(1)XML格式数据

xmlhttp.responseXML

(2)字符串类型数据

xmlhttp.responseText

修改代码后

在这里插入图片描述

再次请求

在这里插入图片描述

GET方法 IE兼容问题
  • XMLHttpRequest对象的IE兼容

使用下面代码创建xmlhttp ,能够具有IE兼容

var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  • IE请求最新数据问题

IE认为同一个URL的内容是固定的,要想实时获得最新数据,必须用不同的url进行请求

解决方案:在url后面加上一段额外字符,没有实际意义,只为了兼容IE

可以使用随机数random也可以使用时间date

xmlhttp.open("GET", "get1_IE.txt?"+(Math.random()), true);
封装Ajax的GET请求
基本封装
  • 意义:每次定义的Ajax操作都是大同小异,为了减少工作量应该把其封装成一个函数
  • 封装方法

需要改变的地方设置成封装方法的参数:

(1)请求的url

(2)成功后的处理 传入一个回调函数success(xhr)

(3)失败时的处理 传入一个回调函数error(xhr)

function myAjaxGet(url, success, error) {
    let btn = document.querySelector("button");
    btn.onclick = function (val) {
        // 1.创建异步对象
        var xmlhttp;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }
        else {// code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        // 2.设置请求方式和地址
        xmlhttp.open("GET", url + '?t=' + (new Date().getTime()), true);
        /*
                open的参数
                01 请求方式 GET / POST
                02 请求地址
                03 同步false/异步true   ajax固定异步,必须是true
            */

        // 3.发送请求
        xmlhttp.send();

        // 4.监听状态
        xmlhttp.onreadystatechange = function (val2) {
            // 5.进行处理
            // 5.1当消息传输完成时才进行处理
            if (xmlhttp.readyState === 4) {
                // 5.2判断消息是否正常传输,没有发生错误
                if (
                    (xmlhttp.status >= 200 && xmlhttp.status < 300) ||
                    xmlhttp.status === 304
                ) {
                    // 5.3对成功状态进行处理
                    success(xmlhttp);

                } else {
                    error(xmlhttp);
                }
            }
        };
    };
}
  • 使用该封装方法
1.引入封装方法的JS文件
<script src="./get_wrap.js"></script>
2.调用该函数,并定义两个回调函数
<script>
        myAjaxGet('get1_IE.txt',(xhr)=>{
            alert(xhr.responseText);
        },(xhr)=>{
            console.log('error!');
        })
 </script>

结果

在这里插入图片描述

将请求内容放到url上
  • 给封装的方法新增一个参数,用来接收要被放在url上的请求内容
  • 将请求封装在一个对象内传递到ajax方法中,即新参数是一个对象
变化:
1.新增方法obj2str
2.myAjaxGet方法新增参数obj
3.方法内部处理url的地方改成 url+"?"+(obj处理成的str)

function obj2str(obj) {
    /*
        obj的格式为 key:val
        将它转成字符串 key1=val1&key2=val2 的形式
    */
    // 将用于兼容IE的时间随机数也放进来一起处理
    obj.t = new Date().getTime();

    let ret = [];
    //    形成[key1=val1,key2=val2]形式的数组
    for (key in obj) {
        ret.push(key + '=' + obj[key]);
    }
    //    把他们变成用&连接的字符串,返回
    return ret.join('&');

}


function myAjaxGet(url, obj, success, error) {
    let btn = document.querySelector("button");
    btn.onclick = function (val) {
        // 0.将obj变成字符串
        let str = obj2str(obj);
        // 1.创建异步对象
        var xmlhttp;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }
        else {// code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        // 2.设置请求方式和地址
        xmlhttp.open("GET", url + "?" + str, true);
        /*
                open的参数
                01 请求方式 GET / POST
                02 请求地址
                03 同步false/异步true   ajax固定异步,必须是true
            */

        // 3.发送请求
        xmlhttp.send();

        // 4.监听状态
        xmlhttp.onreadystatechange = function (val2) {
            // 5.进行处理
            // 5.1当消息传输完成时才进行处理
            if (xmlhttp.readyState === 4) {
                // 5.2判断消息是否正常传输,没有发生错误
                if (
                    (xmlhttp.status >= 200 && xmlhttp.status < 300) ||
                    xmlhttp.status === 304
                ) {
                    // 5.3对成功状态进行处理
                    success(xmlhttp);

                } else {
                    error(xmlhttp);
                }
            }
        };
    };
}
 	<script src="./get_wrap2.js"></script>
    <script>
      myAjaxGet(
        "get2.php",
        {
          name: "Joe",
          age: "18",
          fk: 0,
        },
        (xhr) => {
          alert(xhr.responseText);
        },
        (xhr) => {
          console.log("error!");
        }
      );
    </script>
亿点细节
  • 请求响应的时间不定,为了防止时间过长应该设定一个最长时间,超时就停止请求

  • url中不能出现中文,因此要用JS方法将其转码

修改;
1.myAjaxGet方法新增参数limitTime
2.方法内新增timer变量用于接收定时器id
3.方法内新增定时器,定时器时间为limitTime
4.方法内进行url拼接的地方 URL要用encodeURIComponent方法转码
5.obj2str方法中key和val在push前要用encodeURIComponent方法转码


function obj2str(obj) {
    /*
        obj的格式为 key:val
        将它转成字符串 key1=val1&key2=val2 的形式
    */
    // 将用于兼容IE的时间随机数也放进来一起处理
    obj.t = new Date().getTime();


    let ret = [];
    //    形成[key1=val1,key2=val2]形式的数组
    for (key in obj) {
        ret.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
    }
    //    把他们变成用&连接的字符串,返回
    return ret.join('&');


}

function myAjaxGet(url, obj, limitTime, success, error) {
    let btn = document.querySelector("button");
    btn.onclick = function (val) {
        // 0.将obj变成字符串
        let str = obj2str(obj);
        // 1.创建异步对象
        var xmlhttp, timer;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }
        else {// code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        // 2.设置请求方式和地址
        xmlhttp.open("GET", encodeURIComponent(url) + "?" + str, true);
        /*
                open的参数
                01 请求方式 GET / POST
                02 请求地址
                03 同步false/异步true   ajax固定异步,必须是true
            */

        // 3.发送请求
        xmlhttp.send();

        // 4.监听状态
        xmlhttp.onreadystatechange = function (val2) {
            // 5.进行处理
            // 5.1当消息传输完成时才进行处理
            if (xmlhttp.readyState === 4) {
                //传输完成,清除定时器
                clearInterval(timer);
                // 5.2判断消息是否正常传输,没有发生错误
                if (
                    (xmlhttp.status >= 200 && xmlhttp.status < 300) ||
                    xmlhttp.status === 304
                ) {
                    // 5.3对成功状态进行处理
                    success(xmlhttp);

                } else {
                    error(xmlhttp);
                }
            }
        };
        // 若超时则停止请求
        timer = setInterval(() => {
            console.log('timer out!');
            xmlhttp.abort();//终止请求
            clearInterval(timer);
        }, limitTime);
    };

}
    <script src="./get_wrap3.js"></script>
    <script>
      myAjaxGet(
        "get2.php",
        {
          name: "Joe",
          age: "18",
          fk: 0,
          chinese: "你好",
        },
        3000,
        (xhr) => {
          alert(xhr.responseText);
        },
        (xhr) => {
          console.log("error!");
        }
      );
    </script>
  • 注意事项

url中只能是字母、数字、下划线、ASCII码,其他的都要转码

Ajax-POST方法

基本用法
  • 无表单数据
xmlhttp.open("POST","demo_post.asp",true);
xmlhttp.send();
  • 有表单数据
1.在open和send之间加上setRequestHeader方法
2.将要传递的表单数据作为send的参数传递

xmlhttp.open("POST","ajax_test.asp",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Bill&lname=Gates");
封装POST,并实现同时具有两种模式的方法
修改:
1.方法名为myAjax,增加参数 method 接收传输方式
2.方法内新增if判断,是GET方法还是POST方法
3.GET方法沿用前面封装,POST方法按照上面有表单数据来封装

function obj2str(obj) {

    /*
        obj的格式为 key:val
        将它转成字符串 key1=val1&key2=val2 的形式
    */
    // 将用于兼容IE的时间随机数也放进来一起处理
    obj.t = new Date().getTime();


    let ret = [];
    //    形成[key1=val1,key2=val2]形式的数组
    for (key in obj) {
        ret.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
    }
    //    把他们变成用&连接的字符串,返回
    return ret.join('&');
}

function myAjax(method, url, obj, limitTime, success, error) {
    let btn = document.querySelector("button");
    btn.onclick = function (val) {
        // 0.将obj变成字符串
        let str = obj2str(obj);
        // 1.创建异步对象
        var xmlhttp, timer;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }
        else {// code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        if (method === "GET") {
            // 2.设置请求方式和地址
            xmlhttp.open("GET", encodeURIComponent(url) + "?" + str, true);
            /*
                    open的参数
                    01 请求方式 GET / POST
                    02 请求地址
                    03 同步false/异步true   ajax固定异步,必须是true
                */

            // 3.发送请求
            xmlhttp.send();

            // 4.监听状态
            xmlhttp.onreadystatechange = function (val2) {
                // 5.进行处理
                // 5.1当消息传输完成时才进行处理
                if (xmlhttp.readyState === 4) {
                    //传输完成,清除定时器
                    clearInterval(timer);
                    // 5.2判断消息是否正常传输,没有发生错误
                    if (
                        (xmlhttp.status >= 200 && xmlhttp.status < 300) ||
                        xmlhttp.status === 304
                    ) {
                        // 5.3对成功状态进行处理
                        success(xmlhttp);

                    } else {
                        error(xmlhttp);
                    }
                }
            };
            // 若超时则停止请求
            timer = setInterval(() => {
                console.log('timer out!');
                xmlhttp.abort();//终止请求
                clearInterval(timer);
            }, limitTime);
        } else {
            // 2.设置请求方式和地址
            xmlhttp.open("POST", encodeURIComponent(url), true);
            /*
                    open的参数
                    01 请求方式 GET / POST
                    02 请求地址
                    03 同步false/异步true   ajax固定异步,必须是true
            */

            xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");


            // 3.发送请求
            xmlhttp.send(str);

            // 4.监听状态
            xmlhttp.onreadystatechange = function (val2) {
                // 5.进行处理
                // 5.1当消息传输完成时才进行处理
                if (xmlhttp.readyState === 4) {
                    //传输完成,清除定时器
                    clearInterval(timer);
                    // 5.2判断消息是否正常传输,没有发生错误
                    if (
                        (xmlhttp.status >= 200 && xmlhttp.status < 300) ||
                        xmlhttp.status === 304
                    ) {
                        // 5.3对成功状态进行处理
                        success(xmlhttp);

                    } else {
                        error(xmlhttp);
                    }
                }
            };
            // 若超时则停止请求
            timer = setInterval(() => {
                console.log('timer out!');
                xmlhttp.abort();//终止请求
                clearInterval(timer);
            }, limitTime);
        };
    }

}

    <script src="./get_post.js"></script>
    <script>
      myAjax(
        "POST",
        "get2.php",
        {
          name: "Joe",
          age: "18",
          fk: 0,
          chinese: "你好",
        },
        3000,
        (xhr) => {
          alert(xhr.responseText);
        },
        (xhr) => {
          console.log("error!");
        }
      );
    </script>

仿照jQuery的Ajax 完善封装

method的大小写问题

只能传大写的POST和GET才能正常使用

解决方法

在if判断的时候全部先转为小写再判断
if(method.toLowerCase()==='get'){
	..
}else{
	..
}
参数顺序问题

必须按照顺序接收参数,否则无法正常使用

解决方法

将参数改为一个对象,这样使用其中各属性都是 对象.属性 的方式,不需要关注其顺序(具体实现略)

声明
参数 function myAjax(option){..}
使用 option.url
	option.method
		...


调用
myAjax({
	url:'xx',
	method:'xx',
	...
});

Ajax数据传输

  • 问题提出

服务器如果返回的是简单的字符串数据,会难以区分和使用(比如哪里是用户名哪里是密码)。

简单使用如 “|” 之类的字符进行分割容易引起错误(比如原本数据里就带|符号)

所以需要一种格式化的数据传送方式

Ajax-xml解析

xml格式
  • 头部
<?xml version="1.0" encoding="UTF-8" ?>
  • 标签
所有数据都要放到一个 【根标签】 内,且所有标签的名字都是【自定义】的

<person>
	<name>alex</name>
    <age>18</age>
</person>
服务端php返回xml格式
头部必须加
header("content type:text/xml: charset-utf 8")
返回内容
echo file_get_contents("user.xml");
前端解析xml格式数据

xml格式和html格式的标签获取方式一致

res=xhr.responseXML //获取xml数据
res.querySelector('name')  ==> <name>alex</name>
res.querySelector('name').innerHTML ==> alex 
前端解析JSON数据
接收:
str=xhr.responseText

处理:
str=JSON.stringify(obj) 对象转成JSON字符串形式

obj=JSON.parse(str)  字符串转成JSON对象形式

使用:
obj.name
obj.age

IE兼容性:
引入JSON2.js文件
  • JSON比xml更有优势,体积小、简洁、操作简单

  • JSON处理注意事项

后端可能返回的是非标准的JSON字符串
比如 对象中key没有用双引号
这样的字符串无法使用JSON.parse解析成对象

解决:使用eval来解析
var obj=eval("("+str+")");

用法:eval解析时要将str用()括起来
	既可以解析JSON字符串,也可以解析非标准JSON字符串
	
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值