分享原生Ajax编程优秀博文

本文来自博客园,作者:{lvhanghmm},转载请注明原文链接:https://www.cnblogs.com/lvhanghmm/p/14338911.html

Ajax编程基础

 

Ajax编程基础

传统网站中存在的问题

●网速慢的情况下,页面加载时间长,户只能等待

●表单提交后,如果项内容不合格,需要重新填写所有表单内容

●页面跳转,重新加载页面,造成资源浪费,增加用户等待时间

Ajax概述

Ajax:标准读音['ei d3aeks],幅译:阿贾克斯

它是浏览器提供的一方法,可以实现页面无刷新更新数据,提高用户浏览网站应用的体验。

Ajax的应用场景

1.页面上拉加载更多数据

2.列表数据无刷新分页

3.表单项离开焦点数据验证

4.搜索框提示文字下拉洌表

Ajax的运行环境

Ajax技术需要运行在网站环境中才能生效,当前会使用Node创建的服务器作为网站服务器。

Ajax运行原理及实现

Ajax运行原理

Ajax相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏顺面的情况下,雕更新页面数据,从而提高用户体验。

Ajax的实现步骤

1.创建Ajax对象

// 1 创建Ajax对象
let xhr = new XMLHttpRequest();

2.告诉Ajax请求地址以及方式

// 2 告诉Ajax对象要想哪儿发送请求,以什么方式发送请求
// 1)请求方式2)请求地址
xhr.open('get', 'https://v1.alapi.cn/api/music/search?keyword=小时姑娘');

3.发送请求.

// 发送请求
xhr.send();

4.获取服务器端给与客户端的响应数据

// 获取服务器端响应到客户端的数据!
	xhr.onload = function() {
	console.log(xhr.responseText)
}

效果展示:上面的请求链接来自于接口大全-免费API,收集所有免费的API

服务器端响应的数据格式

你想要看到效果,你首先要新建一个文件夹, 在文件夹里新建一个app.js的文件,然后在新建一个文件夹,里面待会要放html文件! 如下列文字和图片所示:

app.js 这儿我就不再使用上面的接口地址了!我会在本地写地址!用本地的服务器来实现我们的目标!

const express = require('express');
const path = require('path');
// 创建web服务器!
const app = express();
// 引用request模块! 返回一个request函数
// 向其他服务器端请求数据的模块!服务器端是不受同源政策的影响的!
const request = require('request');

// 静态资源服务访问功能!
app.use(express.static(path.join(__dirname, 'lvhang')))
app.listen(3003)
console.log('the backgroundServer is running ! port is 3003')
// console.log(__dirname)
// console.log(path.join(__dirname, 'lvhang'))
// console.log(path.join(__dirname, 'lvhang', 'lvchengxin'))


html代码其实也就是Ajax的实现步骤

<!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>
	<!-- <h1>## Ajax的实现步骤</br> -->
<h1>测试页面!</h1>
<!-- w -->
</h1>
<script type="text/javascript">
		// 1 创建Ajax对象
		let xhr = new XMLHttpRequest();
		// 2 告诉Ajax对象要想哪儿发送请求,以什么方式发送请求
		// 1)请求方式2)请求地址
		// 现在你是访问不了这个地址的会提示你资源无法找到, 很正常, 因为我们还米有配置路由呢!
		// 服务端的请求方式和请求地址一定要和客户端对应起来!
		xhr.open('get', 'http://localhost:3003/test');
		// 发送请求
		xhr.send();
		// 获取服务器端响应到客户端的数据!
		xhr.onload = function() {
		console.log(xhr.responseText)
		}
	</script>
</body>
</html>



然后你需要在控制台界面运行服务器端的程序!


在真实的项目中,务器端大多数情况下会以JSON对象作为响应数据的格式。当客户端拿到响应数据时,要将JSON数据和HTML字符串进行拼接,然后将拼接的结果展示在面中。
要实现上面的需求其实很简单我还是用上面的服务器举例子!我们只需要改一点点东西就行了!
app.js改动点:


在http请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输。

		JSON.parse(); // 将json字符串解析为json对象!

html文件改动点!

		// 获取服务器端响应到客户端的数据!
		xhr.onload = function() {
			let transform = JSON.parse(xhr.responseText)
		console.log(transform);
		let str = '<h1>'+transform.name+'</h1>'
		document.body.innerHTML = str

		}

使用Ajax技术如何传递请求参数

传统网站表单提交

	<form action="get" action="http://www.baidu.com">
		<input type="text" name="username" id="">
		<input type="password" name="password" id="">
	</form>
	<!-- http://www.baidu.com?username=zhangsan&password=123456 -->

Ajax中提交

1 GET请求方式
	xhr.open('get', 'http://localhost:3003/test');

需求:我们需要把表单中的内容发送到服务器端!进行字符串拼接!【username=123&age=456】怎么做!狠狠地做!
当然,还是为了快速完成需求,我还是用上面已经创建好了的服务器!

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>
    <!-- <h1>## Ajax的实现步骤</br> -->
    <h1>测试页面!</h1>
    <p>
        <input type="text" name="username" id="username">
    </p>
    <p>
        <input type="text" name="username" id="password">
    </p>
    <p>
        <button id="btn">提交</button>
    </p>
    <script type="text/javascript">
        let btn = document.getElementById("btn");
        let username = document.getElementById("username");
        let password = document.getElementById("password");

        // 为按钮添加点击事件
        btn.addEventListener("click", function() {

            // 目标:完成usernam=123&age=456的拼接
            // 拼接请求参数
            // 在传统的网站from表单提交中,时已经给我们拼接好了的!
            // Ajax中我们得自己进行拼接了!
            let params = 'username=' + username.value + '&age=' + password.value + '';
            // 1 创建Ajax对象
            let xhr = new XMLHttpRequest();
            // 2 告诉Ajax对象要想哪儿发送请求,以什么方式发送请求
            // 1)请求方式2)请求地址
            // 现在你是访问不了这个地址的会提示你资源无法找到, 很正常, 因为我们还米有配置路由呢!
            // 服务端的请求方式和请求地址一定要和客户端对应起来!
            // 
            // 问号后面就是请求的参数了!
            xhr.open('get', 'http://localhost:3003/test?' + params);
            // 发送请求
            xhr.send();
            // 获取服务器端响应到客户端的数据!
            xhr.onload = function() {
                console.log(xhr.responseText);

            }
        })
    </script>
</body>

</html>

服务器端改动代码:

app.get('/test', (req, res) => {
	// 在服务器端如何接收客户端传递过来的请求参数呢!?!
	// 注意:这个要通过req,query来获取!
      // req.query返回的是一个JavaScript对象?!
	res.send(req.query);
})

2 POST请求方式!

POST请求参数不是放在地址栏后面的,而是放在请求当中的!【将请求参数放在send方法中就可以了!】

get和post请求有一个重要的区别!【post请求必须在请求头【报文】当中明确设置请求参数内容的类型 [也就是Content-Type属性]】

** 对于[usernam=123&age=456]也就是参数名等于参数值,多个参数之间用&符号进行隔开的形式!内容的类型是【application/x-wwww-urlencoded】 如下!**
** 在服务器端我们要如何拿到post请求的参数呢?! 这儿要用到node的第三方模块!body-parser **
服务器端代码的变化!:

app.post('/test', (req, res) => {
    // 在服务器端如何接收客户端传递过来的请求参数呢!? get请求!
    // 注意:这个要通过req.query来获取!
    // res.send(req.query);


    // 然后通过req.body拿到post的请求参数!
    res.send(req.body)

})

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>
    <!-- <h1>## Ajax的实现步骤</br> -->
    <h1>测试页面!</h1>
    <p>
        <input type="text" name="username" id="username">
    </p>
    <p>
        <input type="text" name="username" id="password">
    </p>
    <p>
        <button id="btn">提交</button>
    </p>
    <script type="text/javascript">
        let btn = document.getElementById("btn");
        let username = document.getElementById("username");
        let password = document.getElementById("password");

        // 为按钮添加点击事件
        btn.addEventListener("click", function() {

            // 目标:完成usernam=123&age=456的拼接
            // 拼接请求参数
            // 在传统的网站from表单提交中,时已经给我们拼接好了的!
            // Ajax中我们得自己进行拼接了!
            let params = 'username=' + username.value + '&age=' + password.value + '';
            // 1 创建Ajax对象 
            let xhr = new XMLHttpRequest();
            // 2 告诉Ajax对象要想哪儿发送请求,以什么方式发送请求
            // 1)请求方式2)请求地址
            // 现在你是访问不了这个地址的会提示你资源无法找到, 很正常, 因为我们还米有配置路由呢!
            // 服务端的请求方式和请求地址一定要和客户端对应起来!
            // 
            // 问号后面就是请求的参数了!
            // 第一个值是报文属性名称!
            // 第二个值是报文属性对应的值!
            xhr.open('POST', 'http://localhost:3003/test')
            // application/x-www-urlencoded 是错的, 少了一个单词! form

            // xhr.setRequestHeader('Content-Type', 'application/x-www-urlencoded'); // 这种写法是规定好的!
             xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 这种写法是规定好的!
            // 发送请求
            xhr.send(params);
            // 获取服务器端响应到客户端的数据!
            xhr.onload = function() {
                console.log(xhr.responseText);

            }
        })
    </script>
</body>

</html>

最终效果展示【我的不行, 控制台有响应,但是打印不出我们的输入框中的信息!】后面我在看看!

我找到原因了了!少了一句代码!在服务端的代码里!

请求报文

在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些跏信息,这些数据和信息要遵守规好的格式。

请求参数的格式

   1. application/x-www-form-urlencoded

usernam=123&age=456
2. application/json
{name: 'lvhang', age: 23}
在请求头中指定Content-Type属性的值是application/json,告诉服务器端当前请求参数的格式是json。我们在传递参数的时候要求必须以json对象进行传递!
JSON.stringify() // 将json对象转换为json字符串! 他接收json对象作为参数!作用就是将json对象转化为json字符串!

服务端改动代码[其实就只改了一个地方!就是让浏览器知道这次我们发送的是json的数据格式]:
app.use(bodyParser.json());·

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>
    <!-- <h1>## Ajax的实现步骤</br> -->
    <h1>测试页面!</h1>
    <p>
        <input type="text" name="username" id="username">
    </p>
    <p>
        <input type="text" name="username" id="password">
    </p>
    <p>
        <button id="btn">提交</button>
    </p>
    <script type="text/javascript">
        let btn = document.getElementById("btn");
        let username = document.getElementById("username");
        let password = document.getElementById("password");

        // 为按钮添加点击事件
        btn.addEventListener("click", function() {

            // 目标:完成usernam=123&age=456的拼接
            // 拼接请求参数
            // 在传统的网站from表单提交中,时已经给我们拼接好了的!
            // Ajax中我们得自己进行拼接了!
            // let params = 'username=' + username.value + '&age=' + password.value + '';
            let params = {
                    username: username.value,
                    password: password.value
                }
                // 1 创建Ajax对象 
            let xhr = new XMLHttpRequest();
            // 2 告诉Ajax对象要想哪儿发送请求,以什么方式发送请求
            // 1)请求方式2)请求地址
            // 现在你是访问不了这个地址的会提示你资源无法找到, 很正常, 因为我们还米有配置路由呢!
            // 服务端的请求方式和请求地址一定要和客户端对应起来!
            // 
            // 问号后面就是请求的参数了!
            // 第一个值是报文属性名称!
            // 第二个值是报文属性对应的值!
            xhr.open('POST', 'http://localhost:3003/test')
                // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 这种写法是规定好的!
            xhr.setRequestHeader('Content-Type', 'application/json'); // 这种写法是规定好的!
            // 发送请求
            xhr.send(JSON.stringify(params));
            // 获取服务器端响应到客户端的数据!
            xhr.onload = function() {
                console.log(xhr.responseText);
            }
        })
    </script>
</body>

</html>

最终结果展示:

另一种获取服务端响应的方式!【过时, 作为了解性的知识点!】

Ajax 状态码

在创建ajax对象,配置ajax对象, 发送请求,以及接收完服务器端响应数据,这个过程中的每一个步骤都会对应一 个数值,这个数值就是ajax状态码。

  • 0:请求未初始化(还没有调用open0)
  • 1:请求已经建立,但是还没有发送(还没有调用send0)
  • 2:请求已经发送
  • 3:请求正在处理中,通常响应中已经有部分数据可以用了
  • 4:响应已经完成,可以获取并使用服务器的响应了

** 如何获取状态码 **
xhr.readState // 获取Ajax状态码

onreadystatechange 事件

当Ajax状态码发生变化时将自动触发该事件。

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>
    <!-- <h1>## Ajax的实现步骤</br> -->
    <h1>测试页面!</h1>

    <script type="text/javascript">
        var xhr = new XMLHttpRequest();
        // 0 已经创建了ajax对象 但是还没有对ajax对象进行配置
        console.log(xhr.readyState);
        xhr.open('get', 'http://localhost:3003/test');
        // 1 已经对ajax对象进行配置 但是还没有发送请求
        console.log(xhr.readyState);

        // 当ajax状态码发生变化的时候出发
        xhr.onreadystatechange = function() {
            // 2 请求已经发送了
            // 3 已经接收到服务器端的部分数据了
            // 4 服务器端的响应数据已经接收完成
            console.log(xhr.readyState);
            // 对ajax状态码进行判断 如果状态码的值为4就代表数据已经接收完成了
            if (xhr.readyState == 4) {
                console.log(xhr.responseText);
            }
        }

        xhr.send();
    </script>
</body>

</html>

服务端代码改动点:


app.get('/test', (req, res) => {
    res.send('这种获取服务端响应的方法已经过时了!')
})

效果展示:

** 两种获取服务器端响应方式的区别 **

Ajax 错误处理

  1. 网络畅通,服务器端能接收到请求,服务器端返回的结果不是预期结果。
    ==** 可以判断服务器端返回的状态码,分别进行处理。xhr.status 获取http状态码 ** ==

如何在服务器端返回相应的状态码给客户端呢?!

app.get('/test', (req, res) => {
    res.status(400).send("状态错误!")
})

需求:如何在客户端获取http状态码呢?!
xhr.status // 获取http状态码

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>
    <!-- <h1>## Ajax的实现步骤</br> -->
    <h1>测试页面!</h1>
    <button id="btn">Ajax错误处理</button>
    <script type="text/javascript">
        btn.onclick = function() {
            var xhr = new XMLHttpRequest();
            // 0 已经创建了ajax对象 但是还没有对ajax对象进行配置
            // console.log(xhr.readyState);
            xhr.open('get', 'http://localhost:3003/test');
            // 1 已经对ajax对象进行配置 但是还没有发送请求
            // console.log(xhr.readyState);

            // 当ajax状态码发生变化的时候出发
            // xhr.onreadystatechange = function() {
            //     // 2 请求已经发送了
            //     // 3 已经接收到服务器端的部分数据了
            //     // 4 服务器端的响应数据已经接收完成
            //     console.log(xhr.readyState);
            //     // 对ajax状态码进行判断 如果状态码的值为4就代表数据已经接收完成了
            //     if (xhr.readyState == 4) {
            //         console.log(xhr.responseText);
            //     }
            // }

            xhr.send();

            xhr.onload = function() {
                // console.log(xhr.responseText)
                // console.log(xhr.status); // 400
                if (xhr.status === 400) {
                    alert("请求出错了!")
                }
            }
        }
    </script>
</body>

</html>

效果展示:

可以看到我们成功的拿到了服务器返回给我们的状态码,并进行了判断,执行了相应的代码!

  1. 网络畅通,服务器端没有接收到请求,返回404状态码。
    ** 检查请求地址是否错误。**

将我们html中的请求地址故意改成错的!
我改成了xhr.open('get', 'http://localhost:3003/test1');
效果展示:

所以,以后看到你的服务器爆出如下的状态码错误,你就应该检查一下你的请求地址是不是错了!

  1. 网络畅通,服务器端能接收到请求,服务器端返回500状态码。
    ** 服务器端错误,找后端程序员进行沟通。 **

服务器端代码改动!

效果展示:
温馨提醒一下,就是做完上面的那个栗子后要把请求地址改成正确的偶!

  1. 网络中断,请求无法发送到服务器端。
    ** 会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理。**

将上面的栗子中的服务器中的错误代码注释掉!

html文件改动点!

      // 当网络中断的时候会触发onerror事件
            xhr.onerror = function() {
                console.log("网络中断,无法发送Ajax请求!")
            }

Ajax状态码:表示Ajax请求的过程状态ajax对象返回的
Http状态码:表示请求的处理结果是服务器端返回的

然后来到浏览器刷新以下页面,打开控制台,进入network选项!选中offline,点击按钮发送请求!
效果展示:

低版本IE浏览器的缓存问题!

问题:在低版本的lE浏览器中,Ajax 请求有严重的缓存问题,即在请求地址不发生变化的情况下,只有第
一次请求会真正发送到服务器端, 后续的请求都会从浏览器的缓存中获取结果。即使服务器端的数据更新了
,客户端依然拿到的是缓存中的旧数据。

Ajax 异步编程

同步异步概述

同步:

  • 一个人同一时间只能做件事情,只有一 件事情做完,才能做另外-件事情。
  • 落实到代码中,就是上一行代码执行完成后,才能执行下一行代码,即代码逐行执行。
console.log('before');
console.log('after');

异步

  • 一个人一件事情做了一半,转而去做其他事情,当其他事情做完以后,再回过头来继续做之前未完成
    的事情。
  • 落实到代码上,就是异步代码虽然需要花费时间去执行,但程序不会等待异步代码执行完成后再继续
    执行后续代码,而是直接执行后续代码,当后续代码执行完成后再回头看异步代码是否返回结果,如
    果已有返回结果,再调用事先准备好的回调函数处理异步代码执行的结果。
console.log('before');

 setTimeout(() => {
                console.log('last');
            }, 2000)

console.log('after');

上面所说的异步对应在Ajax里面就是onload事件!
其实不用在Ajax请求里面测试代码的执行顺序!

你就说这个代码的执行顺序是什么,你就明白在Ajax里面代码的执行顺序了!

console.log('before');

 setTimeout(() => {
                console.log('last');
            }, 2000)

console.log('after');

Ajax 封装

问题:发送次请求代码过多,发送多次请求代码冗余且重复。
解决方案:将请求代码封装到函数中,发请求时调用函数即可。

本文来自博客园,作者:{lvhanghmm},转载请注明原文链接:https://www.cnblogs.com/lvhanghmm/p/14338911.html

 
posted @ 2022-03-31 18:40  RHCHIK  阅读(34)  评论(0编辑  收藏  举报