原生 AJAX 详解

JavaScript/前端
39
0
0
2024-07-03
标签   Ajax

Ajax

Ajax 技术是 javascript 中最重要的一个组成部分,不会 Ajax,你写的就是一个死页面。Ajax 是与后台来连接数据的。
Ajax 是什么?

Ajax 即 “Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互网页应用的网页开发技术(用来向后台数据库请求获取数据的技术)。

传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

Ajax 除了解决局部更新渲染页面的问题,也解决了前后端分离的问题。

前后端分离的必要性

用户的计算机中无法存储大量的数据,因此就需要将数据存储在后台数据库中,前端页面中需要使用数据的时候,就向后台数据库发送请求获取数据进而渲染数据显示页面

示例如下

分三步

  1. 发请求
  2. 后台做响应
  3. 前端接到数据做渲染

原生 Ajax

安装本地服务器集成环境

使用 wampserver 集成服务器

注意:选择安装路径必须使用纯英文路径

Wamp 的使用
  1. 启动wamp软件(小图标变绿,启动成功)
  2. 在浏览器地址栏输入 127.0.0.1(本地服务器的 ip 地址)
  3. 如果想使用wamp运行自己的代码,需要将要运行的代码存放进wamp安装目录下的www文件夹中
  4. 存入之后在127.0.0.1地址对应的页面中即可打开文件
  5. 在wamp中打开的页面实际上就是在使用服务器环境打开页面
Ajax 数据交互过程

具体过程

  1. 创建对象
let ajax = new XMLHttpRequest()
  1. 建立前后端连接
ajax.open('请求方式',url地址,是否异步)
  1. 发送请求
ajax.send()
  1. 监听通信状态码改变

什么叫通信状态码 ?

1)通信状态码是用来记录数据交互状态

a. 0: 表示 ajax 的对象还没有创建出来

b. 1: ajax 对象调用了 open,建立了前后端之间的连接

c. 2: ajax 对象调用了 send,发送了请求

d. 3: 后台服务器解析请求,分析请求中需要的数据

e. 4: 后台服务器将数据响应给前端

2)如果通信状态码为 4,证明响应完成,我们就可以在前端获取响应数据了

ajax.onreadystatechange = function() {
    if(ajax.readyState == 4){
        console.log(ajax.responseText)
    }
}
  1. 监测请求和响应过程中是否出问题

我们通过响应状态码来监测这个状态

什么是响应状态码 ?

1) 响应状态码是用来记录数据交互过程中是否出问题的标识

a. 200: 请求响应成功,数据来源于后台数据库

b. 304: 请求响应成功,数据来源于本地缓存

c. 403: 请求响应失败,没有权限访问

d. 404: 请求响应失败,访问地址有误

e. 500及以上: 后端服务器问题

2)区分 200 和 304

200 请求响应成功,它获得的数据是来源于后台数据库的

304 请求响应成功,它获得的数据是来源于本地缓存的,也就是说这个数据咱已经请求过一次了,本地已经将其缓存下来了,本地缓存的目的就在于避免再重新向后台数据库进行一个新的请求,比较节省时间,提高响应速度。

ajax.onreadystatechange = function() {
    if(ajax.readyState == 4){
        if(ajax.status == 200 || ajax.status == 304){
            console.log(ajax.responseText)
        }
    }
}

完整代码示例

/*发请求 可以类似于打电话: */ 

//1. 装电话 安装电话的过程其实就是创建这个对象
// javascript 中有一个内置对象专门用来处理ajax数据交互,该对象是: XMLHttpRequest

let ajax = new XMLHttpRequest();

//2. 连电话线 连电话线的过程其实就是建立前端和后台之间的连接
// 建立连接的方法是 XMLHttpRequest对象 的一个方法 send

ajax.open('get','./data.txt',true);

//3. 打电话 打电话的过程其实就是向后台数据库发送请求
// 发送请求的方法是 XMLHttpRequest对象 的一个方法 send

ajax.send();

/*
* 当电话打通后,服务器会自动地解析请求中需要的数据,并发送数据
* 前端接下来需要监听数据是否接受到,如果到了,就可以开始使用数据进行渲染
*/ 

//4. 监测数据 在 XMLHttpRequest对象 有一个 onreadystatechange事件
// onreadystatechange事件可以监测数据响应到什么程度
// on readystate(通信状态码) change(改变)
// 在数据交互的过程中 每当通信状态码改变的时候 就会触发这个事件

ajax.onreadystatechange = function(){
    //如果通信状态码为 4 就获取数据
    //XMLHttpRequest对象的readyState属性就是通信状态码
    if(ajax.readyState == 4) {
        //响应数据就是XMLHttpRequest对象的responseRequest属性
        //还需监测请求响应过程中是否出问题
        // 通过响应状态码 state 来监测
        if(ajax.state == 200 || ajax.state == 304) {
            console.log(ajax.responseRequest)
        }
    }
}
ajax 请求方式之 get 与 post
get 方式

使用 get 请求方式时,我们可以将要提交的数据放置于url地址后面进行提交。

url?键名1=键值&键名2=键值&键名3=键值…

代码示例

    let ajax = new XMLHttpRequest();
    ajax.open(' get ', ' ./data.txtEname=gd&age=18&sex=boy ', true);
    ajax.send();
    ajax.onreadystatechange = function () {
        if (ajax.readyState == 4) {
            if (ajax.status == 200 || ajax.status == 304) {
                console.log(ajax.responseText)
            }
        }
    }

弊端

安全性不高,因为用户提交的数据都会显示在地址栏中,因此 get 不适用于登录注册页面。

提交数据的量很小,大概只有 4kb 左右,不适用于大量数据的提交。

优点

传输数据的速度较快

post 方式


提交数据的方式:将要提交额数据作为 send 方法的参数传入
ajax.send('键名1=键值&键名2=键值&键名3=键值...')

注意

post 方式发送请求需要设置请求头(请求报文的一部分)

那么什么是请求报文?

就是发送的请求实际上是一个已经打包好的信息,然后这个包发送过去。

请求报文中包含三部分内容 : 请求命令行 请求头 请求主体

ajax.setRequestHeader('Content-tepe', 'application/x-www-form-urlencoded');

优点

安全性好

提交的数据大小大概有 20Mb

代码示例

    let ajax = new XMLHttpRequest();
    ajax.open('post', './data.txt', true);
    // post 请求需要在 open 之后,send 之前,设置请求头
    ajax.setRequestHeader('Content-tepe', 'application/x-www-form-urlencoded');
    ajax.send('name=gd&age=18&sex=boy');
    ajax.onreadystatechange = function () {
        if (ajax.readyState == 4) {
            if (ajax.status == 200 || ajax.status == 304) {
                console.log(ajax.responseText)
            }
        }
    }

封装一个 Ajax 方法

封装函数步骤
  1. 写入主体代码
  2. 提出不确定的数据作为参数
  • 请求方式和提交数据的的方式不确定
  • url 地址不确定
  • 提交的数据不确定
  1. 将参数代入函数中
  2. 调用测试

代码示例

    let ajax = function (url,method,data,fn) {
        let xml = new XMLHttpRequest();
        // 判断 
        if(method =='get'){
            xml.open(method,url+'?'+data, true);
        }else if(method =='post'){
            xml.open(method,url,true);
            xml.setRequestHeader('Content-tepe', 'application/x-www-form-urlencoded');
            xml.send('name=gd&age=18&sex=boy');
        }
        // 获取响应数据
        xml.onreadystatechange = function () {
            if (xml.readyState == 4) {
                if (xml.status == 200 || xml.status == 304) {
                    // 让外界能够拿到响应数据 使用回调函数来实现
                    // 如果响应数据成功 就调传用入的回调函数 fn
                    fn(xhr.responseText)
                }
            } 
        }
    }
    ajax('data.txt','get','',function(res){
        console.log(res)
    }) 

Ajax 操作数组和json数据

操作数组

目录文件夹

ajax.js 插件

let ajax = function (url, method, data, fn) {
    let xml = new XMLHttpRequest();
    // 判断 
    if (method == 'get') {
        xml.open(method, url + '?' + data, true);
    } else if (method == 'post') {
        xml.open(method, url, true);
        xml.setRequestHeader('Content-tepe', 'application/x-www-form-urlencoded');
        xml.send('name=gd&age=18&sex=boy');
    }
    // 获取响应数据
    xml.onreadystatechange = function () {
        if (xml.readyState == 4) {
            if (xml.status == 200 || xml.status == 304) {
                // 让外界能够拿到响应数据 使用回调函数来实现
                // 如果响应数据成功 就调传用入的回调函数 fn
                fn(xhr.responseText)
            }
        }
    }
}

引用插件

<!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>
    <!-- 引入封装的 ajax -->
    <script src="./ajax.js"></script>
    <script>
        ajax('./data1.txt', 'post', true, function (res) {
            console.log(res, typeof res)
        })
    </script>
</body>

</html>
---控制台---
[1,2,3,4,5,6] string

原生JavaScript通过ajax请求的数据返回的结果为字符串格式

也即 [1,2,3,4,5] 返回的结果为 “[1,2,3,4,5]”

eval() 方法: eval() 函数可计算某个字符串,并执行其中的 JavaScript 代码,可以将字符串数组转换为正则的js数组数据类型数据。

let res1 = eval(res)
console.log(res1)
---控制台---
Array(6) [1,2,3,4,5,6]
操作 Json 数据

Json 的书写规则

  • Json 文件中只能写一个数据
  • Json 中不可以写注释
  • Json 中只能使用双引号,不能使用单引号
  • Json 数据不论数组还是对象,最后一个数组项后属性后面都不能加逗号
  • Json 对象的属性名必须要是双引号

所以采用以下两种方法,来存多个数据

  1. Json 数组

代码示例

[
    "123",
    "456"
]
  1. Json 对象
{
    "name": "Alian",
    "age": 18
}

Json 文件

{
    "name": "Alian",
    "age": 18
}

ajax.js 插件

let ajax = function (url, method, data, fn) {
    let xml = new XMLHttpRequest();
    // 判断 
    if (method == 'get') {
        xml.open(method, url + '?' + data, true);
    } else if (method == 'post') {
        xml.open(method, url, true);
        xml.setRequestHeader('Content-tepe', 'application/x-www-form-urlencoded');
        xml.send('name=gd&age=18&sex=boy');
    }
    // 获取响应数据
    xml.onreadystatechange = function () {
        if (xml.readyState == 4) {
            if (xml.status == 200 || xml.status == 304) {
                // 让外界能够拿到响应数据 使用回调函数来实现
                // 如果响应数据成功 就调传用入的回调函数 fn
                fn(xhr.responseText)
            }
        }
    }
}

引用插件

<!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>
    <!-- 引入封装的 ajax -->
    <script src="./ajax.js"></script>
    <script>
        ajax('./data.json', 'post', function (res) {
            console.log(res,typeof res);
        })
    </script>
</body>

</html>
---控制台---
{
    "name": "Alian",
    "age": 18
}

string

通过控制台的打印我们可以看到,返回的数据仍然是字符串。

json 数据可以使用 JSON.parse(json数据) 方法将json数据转换为js的对象和数组。

ajax('./data.json','post','',function(res) {
     console.log(res, typeof res);
     console.log(JSON.parse(res));
})