学习AJAX

第一章:原生 AJAX

1.1 AJAX 简介

  • AJAX 全称为 Asynchronous Javascript And XML,即异步 JS 和 XML
  • 通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新网页获取数据
  • AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式

1.2 XML 简介

  • XML:可扩展标记语言
  • XML:被设计用来传输和存储数据
  • XML 和 HTML 类似,不同点:HTML 中都是预定义标签,XML 中没有预定义标签,全是自定义标签,用来表示一些数据
  • 现在已被 JSON 取代

1.3 AJAX 的特点

1.3.1 AJAX 的优点

  1. 可以无刷新页面与服务端进行通信
  2. 允许你根据用户事件来更新部分页面内容

1.3.2 AJAX 的缺点

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. SEO 不友好(爬虫获取不到信息)

1.4 HTTP 协议

1.4.1 HTTP 请求报文

  1. 请求行
method url
GET /product_detail?id=2
POST /login
  1. 多个请求头
Host: www.baidu.com
Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3B0FA706;
Content-Type: application/x-www-form-urlencoded 或者 application/json
  1. 请求体
username=tom&pwd=123
{"username": "tom", "pwd": 123}

1.4.2 HTTP 响应报文

  1. 响应状态行
status statusText
  1. 多个响应头
Content-Type: text/html;charset=utf-8
Set-Cookie: BD_CK_SAM=1;path=/
  1. 响应体
html 文本/json 文本/js/css/图片...

1.4.3 post 请求体参数格式

  1. Content-Type: application/x-www-form-urlencoded;charset=utf-8
用于键值对参数,参数的键值用=连接, 参数之间用&连接
例如: name=%E5%B0%8F%E6%98%8E&age=12
  1. Content-Type: application/x-www-form-urlencoded;charset=utf-8
用于 json 字符串参数
例如: {"name": "%E5%B0%8F%E6%98%8E", "age": 12}
  1. Content-Type: multipart/form-data
用于文件上传请求

1.4.2 常见的响应状态码

  • 200 OK 请求成功。一般用于GET 与POST 请求
  • 201 Created 已创建。成功请求并创建了新的资源
  • 401 Unauthorized 未授权/请求要求用户的身份认证
  • 404 Not Found 服务器无法根据客户端的请求找到资源
  • 500 Internal Server Error 服务器内部错误,无法完成请求

1.4.3 不同类型的请求及其作用

  • GET: 从服务器端读取数据(查)
  • POST: 向服务器端添加新数据 (增)
  • PUT: 更新服务器端已经数据 (改)
  • DELETE: 删除服务器端数据 (删)

1.4.4 API 的分类

REST API: restful (Representational State Transfer (资源)表现层状态转化)

  1. 发送请求进行 CRUD 哪个操作由请求方式来决定
  2. 同一个请求路径可以进行多个操作
  3. 请求方式会用到 GET/POST/PUT/DELETE

非 REST API: restless

  1. 请求方式不决定请求的CRUD 操作
  2. 一个请求路径只对应一个操作
  3. 一般只有GET/POST

1.4.5 区别 一般 HTTP 请求 与 AJAX 请求

AJAX 请求 是一种特别的 HTTP 请求
对服务器端来说, 没有任何区别, 区别在浏览器端
浏览器端发请求: 只有 XHR 或 fetch 发出的才是 AJAX 请求, 其它所有的都是非 AJAX 请求

浏览器端接收到响应

  1. 一般请求: 浏览器一般会直接显示响应体数据, 也就是我们常说的刷新/跳转页面
  2. AJAX 请求: 浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据

第二章:原生 AJAX 的基本使用 XHR

2.1 核心对象(XML)使用步骤

  1. 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
  1. 设置请求信息
// 请求方式  method = get/post...   url = https://www.gitee……
xhr.open(method, url);
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  1. 发送请求
xhr.send(body) //get请求不传 body 参数,只有post请求使用
  1. 接收响应(事件绑定,处理服务端返回的结果)
//xhr.responseXML 接收 xml格式 的响应数据
//xhr.responseText 接收 文本格式 的响应数据
xhr.onreadystatechange = function (){
	// readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4
	if(xhr.readyState == 4 && xhr.status == 200){
		var text = xhr.responseText;
		console.log(text);
	}
}

4.1 readystate

0:未初始化
1:open 方法调用完毕
2:send 方法已经调用完毕
3:服务端返回的部分结果
4:服务器端返回的全部结果

2.2 GET 请求

  1. 服务端代码
@WebServlet("/login")
public class DemoService extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应头,通过一个头 Content-Type 告知客户端使用何种码表进行编码
        // 旧:response.setHeader("Context-Type", "text/html;charset=UTF-8"); // 文本为 html 类型, 编码为 utf-8
        response.setContentType("text/html;charset=UTF-8");
        // 设置响应体
        PrintWriter writer = response.getWriter();
        writer.write("你好");
    }
}
  1. 客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>GET 请求方式</title>
</head>
<body>
<button>点击</button>
<h2 id="result"> </h2>
<script>
    // 获取 buttom 元素
    const btn = document.getElementsByTagName('button')[0];
    // 绑定事件
    btn.onclick = function () {
        // 1、创建对象
        const xhr = new XMLHttpRequest();
        const res = document.getElementById("result")
        // 2、初始化,设置请求方法和URL  2.1 设置 url 参数的一种方式
        xhr.open('GET','http://localhost:8080/ajax01/succeed.html?name=tom&sex=男&age=12')
        // 3、发送
        xhr.send();
        // 4、事件绑定 处理服务器返回结果
        // on when 当。。。时候
        // readystate 是 xhr 对象中的属性,表示状态 0 1 2 3 4
        // change 改变
        xhr.onreadystatechange = function () {
            // 判断(服务器端是否返回了所有的结果)
            if(xhr.readyState == 4){
                // 判断响应状态码 200 404 403 401 500
                // 2xx 成功
                if(xhr.status >= 200 && xhr.status < 300){
                    // 处理结果 行 头 空行 体
                    // 1、响应行
                    console.log(xhr.status); // 状态码
                    console.log(xhr.statusText); // 状态字符串
                    console.log(xhr.getAllResponseHeaders()); // 所有响应头
                    console.log(xhr.response); // 响应体

                    // 设置 res 的文本
                    res.innerHTML = xhr.response;
                }else {
                    console.log('失败');
                }
            }
        }
    }
</script>
</body>
</html>

2.3 post 请求

  1. 服务端代码
@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /* 允许跨域的主机地址 */
    response.setHeader("Access-Control-Allow-Origin", "*");
    /* 允许跨域的请求方法GET, POST, HEAD 等 */
        response.setHeader("Access-Control-Allow-Methods", "*");
    // 设置响应头
    response.setContentType("text/html;charset=UTF-8");
    // 设置响应体
    PrintWriter writer = response.getWriter();
    writer.write("你好");
}
  1. 前端代码
<!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>Ajax POST 请求</title>
  <style>
    #result {
      width: 200px;
      height: 100px;
      border: solid 1px #903;
    }
  </style>
</head>
<body>
  <div id="result"></div>
  <script>
    // 获取元素对象
    const result = document.getElementById('result');
    // 绑定事件
    result.addEventListener("mouseover", function(){
      // 1. 创建对象
      const xhr = new XMLHttpRequest();
      // 2. 初始化 设置类型(请求方式)与url
      xhr.open('POST', 'http://127.0.0.1:8000/server');
      // 3. 发送   设置请求参数(请求体)
      xhr.send('a=100&b=200&c=300');
      // 4. 事件绑定
      xhr.onreadystatechange = function(){
        // 判断
        if(xhr.readyState === 4){
          if(xhr.status >=200 && xhr.status < 300){
            // 处理服务端返回的结果
            result.innerHTML = xhr.response;
          }
        }
      }
    });
  </script>
</body>
</html>

2.4 json 数据格式

  1. 服务端代码
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 设置响应头,通过一个头 Content-Type 告知客户端使用何种码表进行编码
    // 旧:response.setHeader("Context-Type", "text/html;charset=UTF-8"); // 文本为 html 类型, 编码为 utf-8
    response.setContentType("text/html;charset=UTF-8");
    // 创建一个 json 对象
    JSONObject obj = new JSONObject();
    obj.put("name","张三");
    // 将 json 对象转换为字符串
    String str = JSON.toJSONString(obj);
    // 设置响应体
    PrintWriter writer = response.getWriter();
    writer.write(str);
}
  1. 前端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>GET 请求方式</title>
</head>
<body>
<button>点击</button>
<h2 id="result"> </h2>
<script>
    // 获取 buttom 元素
    const btn = document.getElementsByTagName('button')[0];
    const res = document.getElementById("result")
    // 绑定事件
    btn.addEventListener("mouseover", function () {
        // 1 创建对象
        const xhr = new XMLHttpRequest();
        // *2*.(自动转换) 设置响应体数据的类型(自动转换)
        xhr.responseType = 'json';
        // 2 初始化 设置类型 与 URL
        xhr.open("get","http://localhost:8080/ajax01/login")
        // 3 发送 post 可以设置参数 任意格式,只要后端能处理就行
        // xhl.send("123456")
        // xhl.send("name=q|&age=12|set=女")
        xhr.send()
        // 设置请求头
        // xhl.setRequestHeader('Content-Type','application/x-www-from-urlencoded');
       // xhl.setRequestHeader('name','costom');
        // 4 事件绑定
        xhr.onreadystatechange = function () {
            // 判断
            if(xhr.readyState == 4){
                if(xhr.status >= 200 && xhr.status < 300){
                    // 手动将字符串转成 json 对象
                    // let  data = JSON.parse(xhl.response);
                    // 自动装换
                    console.log(xhr.response)
                    // 处理服务端返回的结果
                    res.innerHTML = xhr.response.name;
                }else{
                    console.log("失败")
                }
            }
        }
    })
</script>
</body>
</html>

2.1 自动转换

// 2.(自动转换) 设置响应体数据的类型(自动转换)
xhr.responseType = 'json';
  1. 演示

test

2.5 请求超时与网络异常

// 超时设置 (2秒)
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){
	alert('网络超时,请稍后重试')
}
// 网络异常回调
xhr.onerror = function(){
	alert('网络异常,请稍后重试')
}

2.6 取消请求

// 手动取消
xhr.abort()

2.7 请求重复发送问题

<script>
        //获取元素对象
        const btns = document.querySelectorAll('button');
        let x = null;
        //标识变量
        let isSending = false; // 是否正在发送AJAX请求

        btns[0].onclick = function(){
            //判断标识变量
            if(isSending) x.abort();// 如果正在发送, 则取消该请求, 创建一个新的请求
            x = new XMLHttpRequest();
            //修改 标识变量的值
            isSending = true;
            x.open("GET",'http://127.0.0.1:8000/delay');
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    //修改标识变量
                    isSending = false;
                }
            }
        }

        // abort
        btns[1].onclick = function(){
            x.abort();
        }
    </script>

2.8 解决 IE 缓存问题

问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
解决方案:浏览器的缓存是根据url 地址来记录的,所以我们只需要修改url 地址即可避免缓存问题

xhr.open("get","/testAJAX?t="+Date.now());

2.9 AJAX 请求状态

在这里插入图片描述

  • 0: 表示XMLHttpRequest 实例已经生成,但是open()方法还没有被调用
  • 1: 表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定HTTP请求的头信息
  • 2: 表示send()方法已经执行,并且头信息和状态码已经收到
  • 3: 表示正在接收服务器传来的body 部分的数据
  • 4: 表示服务器数据已经完全接收,或者本次接收已经失败了

2.10 API总结

  • XMLHttpRequest():创建 XHR 对象的构造函数
  • status:响应状态码值,如 200、404
  • statusText:响应状态文本,如 ’ok‘、‘not found’
  • readyState:标识请求状态的只读属性 0-1-2-3-4
  • onreadystatechange:绑定 readyState 改变的监听
  • responseType:指定响应数据类型,如果是 ‘json’,得到响应后自动解析响应
  • response:响应体数据,类型取决于 responseType 的指定
  • timeout:指定请求超时时间,默认为 0 代表没有限制
  • ontimeout:绑定超时的监听
  • onerror:绑定请求网络错误的监听
  • open():初始化一个请求,参数为:(method, url[, async])
  • send(data):发送请求
  • abort():中断请求 (发出到返回之间)
  • getResponseHeader(name):获取指定名称的响应头值
  • getAllResponseHeaders():获取所有响应头组成的字符串
  • setRequestHeader(name, value):设置请求头

第三章:jQuery 中的 AJAX

3.1 get 请求

$.get(url, [data], [callback], [type])
  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
    例子
$('button').eq(0).click(function () {
            // data 就是响应体
            $.get('http://localhost:8080/ajax01/login',{a:100,b:200},function (data) {
                console.log(data)
            },'json')
        })

3.2 post 请求

$.post(url, [data], [callback], [type])
  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
    例子
$('button').eq(1).click(function () {
            $.post('http://localhost:8080/ajax01/login',{a:100,b:200},function (data) {
                console.log(data)
            })
        })

3.3 通用方法

$('button').eq(2).click(function () {
    $.ajax({
        // url 需要向那个资源请求
        url: 'http://localhost:8080/ajax01/login',
        // 参数 向服务端传数据
        data: {a:100,b:200},
        // 请求类型 GET/POST/PUT/DELETE
        type: 'GET',
        // 响应体结果,服务端返回的数据格式,不写就是字符串
        dataType: 'json',
        // 成功的回调 data 就是响应体
        success: function (data) {
            console.log(data)
        },
        // 超时时间
        timeout: 2000,
        // 失败的回调
        error: function () {
            console.log('出错啦!!!')
        },
        // 头信息
        headers: {
            c:300,
            d:400
        }
    })
})

3.4 Axios 函数发送 AJAX 请求

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>axios 发送 AJAX请求</title>
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
</head>

<body>
    <button>GET</button>
    <button>POST</button>
    <button>AJAX</button>

    <script>
        // https://github.com/axios/axios
        const btns = document.querySelectorAll('button');

        //配置 baseURL
        axios.defaults.baseURL = 'http://127.0.0.1:8000';

        btns[0].onclick = function () {
            //GET 请求
            axios.get('/axios-server', {
                //url 参数
                params: {
                    id: 100,
                    vip: 7
                },
                //请求头信息
                headers: {
                    name: 'atguigu',
                    age: 20
                }
            }).then(value => {
                console.log(value);
            });
        }

        btns[1].onclick = function () {
            axios.post('/axios-server', {
                username: 'admin',
                password: 'admin'
            }, {
                //url 
                params: {
                    id: 200,
                    vip: 9
                },
                //请求头参数
                headers: {
                    height: 180,
                    weight: 180,
                }
            });
        }
    
        btns[2].onclick = function(){
            axios({
                //请求方法
                method : 'POST',
                //url
                url: '/axios-server',
                //url参数
                params: {
                    vip:10,
                    level:30
                },
                //头信息
                headers: {
                    a:100,
                    b:200
                },
                //请求体参数
                data: {
                    username: 'admin',
                    password: 'admin'
                }
            }).then(response=>{
                //响应状态码
                console.log(response.status);
                //响应状态字符串
                console.log(response.statusText);
                //响应头信息
                console.log(response.headers);
                //响应体
                console.log(response.data);
            })
        }
    </script>
</body>

</html>

3.5 fetch 函数发送 AJAX 请求

<script>
    //文档地址
    //https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
    
    const btn = document.querySelector('button');

    btn.onclick = function(){
        fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
            //请求方法
            method: 'POST',
            //请求头
            headers: {
                name:'atguigu'
            },
            //请求体
            body: 'username=admin&password=admin'
        }).then(response => {
            // return response.text();
            return response.json();
        }).then(response=>{
            console.log(response);
        });
    }
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值