AJAX(1):原生AJAX,HTTP协议,Ajax环境配置,AJAX发送请求,AJAX请求中的问题

时间:2024-12-11 07:02:25

一.原生AJAX

1.什么是ajax

AJAX全程为Asynchronous Javascript And XML,异步的js和XML

通过AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

 语言

可扩展标记语言。XML被设计用来传输和存储数据。XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全部都是自定义标签,用来表示一些数据。(目前已经被JSON取代)

特点:

优点:
(1)可以无需刷新页面而与服务器端进行通信。
(2)允许你根据用户事件(鼠标事件,文档事件)来更新部分页面内容。
缺点:
(1)没有浏览历史,不能回退。
(2)存在跨域问题(同源)
(3)SEO不友好(查看源代码中无法查找到)

二.HTTP协议

HTTP全称为hypertext transport protocol 协议【超文本传输协议】,协议详细规定了浏览器和万维网服务器之间互相通信的规则。约定了请求和响应格式与参数

请求报文:Request Headers

:请求类型(get,post)   /   url类型()  / HTTP协议版本  /  

:Host:值 Cookie: 值 Content-type:值 User-Agent:值

空行:固定的

:如果是GET请求体为空,如果是POST可以不为空

响应报文:Response Headers

行: HTTP协议版本(1.1) / 响应状态(200)  /响应状态字符串(ok)

头:Content-type:值 Content-length:值 Content-encoding:值等等

空行:

体:HTML语法内容

三.AJAX环境配置

1.下载安装配置环境

下载安装node.js后需要安装,只需要在vscode => 终端 => 当前目录中 => 输入npm i express;

然后引入express,

  1. // 1.引入express
  2. const express = require('express');
  3. // 2.创建应用对象
  4. const app = express();
  5. // 3.创建路由规则
  6. //request封装请求报文
  7. //response封装响应报文
  8. app.get('/', (request, response) => {
  9. //设置响应
  10. response.send('HELLO EXPRESS')
  11. });
  12. //4.监听端口启动服务
  13. (8000, () => {
  14. ('服务已启动,8000端口监听中。。。。。');
  15. })

  

然后浏览器输入:127.0.0.1:8000可以看到响应信息 

 当出现端口被占用报错时: address already in use :::8000或者如下图node时,可使用ctrl+c实现端口释放

四.AJAX发送请求

1.发送请求准备

  1. <head>
  2. <meta charset="UTF-8">
  3. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  4. <title>Document</title>
  5. <style>
  6. .box {
  7. width: 200px;
  8. height: 100px;
  9. border: 1px solid #60cc;
  10. }
  11. </style>
  12. </head>
  13. <body>
  14. <button>发送</button>
  15. <div class="box"></div>
  16. </body>
  1. // 1.引入express
  2. const { response } = require('express')
  3. const express = require('express')
  4. // 2.创建应用对象
  5. const app = express()
  6. // 3.创建路由规则
  7. app.get('/server', (request, response) => {
  8. //设置响应头 设置允许跨域
  9. ('Access-Control-Allow-Origin', '*');
  10. //设置响应体
  11. response.send('HELLO AJAX')
  12. })
  13. // 4.监听端口启动服务
  14. (8000, () => {
  15. ('服务已启动,8000端口监听中。。。。。');
  16. })

发送Get请求

  1. <style>
  2. .box {
  3. width: 200px;
  4. height: 100px;
  5. border: 1px solid #60cc;
  6. }
  7. </style>
  1. <button>发送</button>
  2. <div class="box"></div>

server.js

  1. // 1.引入express
  2. const express = require('express')
  3. // 2.创建应用对象
  4. const app = express()
  5. // 3.创建路由规则
  6. app.get('/server', (request, response) => {
  7. //设置响应头 设置允许跨域
  8. ('Access-Control-Allow-Origin', '*');
  9. //设置响应体
  10. response.send('HELLO AJAX')
  11. })
  12. // 4.监听端口启动服务
  13. (8000, () => {
  14. ('服务已启动,8000端口监听中。。。。。');
  15. })

点击发送将响应体添加到文本框获取文本

onreadystatechange:on当...时; readystate是xhr对象中的属性,表示状态0 1 2 3 4 

change改变

其中0 为未初始化 ;1为 open调用完毕 ;2 :send调用完毕 3 :服务端返回了部分结果 4: 服务端返回了所有结果

  1. <script>
  2. // 获取button元素\
  3. const btn = ('button')[0]
  4. const result = ('.box')
  5. //绑定事件
  6. = function () {
  7. // 1.创建对象
  8. const xhr = new XMLHttpRequest()
  9. //2初始化 设置请求请求方法和url
  10. xhr.open('GET', 'http://127.0.0.1:8000/server')
  11. // 3.发送
  12. xhr.send();
  13. // 4.事件绑定,处理服务端返回的结果
  14. //on当...时; readystate是xh对象中的属性,表示状态0 1 2 3 4 change改变
  15. // 其中0 - 未初始化 1 - open调用完毕 2 - send调用完毕 3 - 服务端返回了部分结果 4 - 服务端返回了所有结果
  16. = function () {
  17. // 判断(假设服务端返回了所有结果)
  18. if ( === 4)
  19. // 判断响应状态 200 404 403 500
  20. // 2开头的响应状态均为成功 203 201
  21. if (xhr.status >= 200 && xhr.status < 300) {
  22. //处理结果 行 头 空行 体
  23. // 1.响应行
  24. /* (xhr.status);//状态码
  25. ();//状态字符串
  26. (());//所有响应头
  27. ();//响应体 */
  28. // 设置box内文本
  29. =
  30. }
  31. }
  32. }
  33. </script>

get传递参数:在url后缀参数,使用 分隔,=赋值,比如   ?a=100&b=200&c=300

发送post请求

  1.  <style>
  2.         .result {
  3.             width: 200px;
  4.             height: 100px;
  5.             border: 1px solid red;
  6.         }
  7.     </style>
  8. </head>
  9. <body>
  10.     <div class="result"></div>

首先获取盒子,为其添加鼠标移动事件

然后创建XMLHttpRequest对象;并初始化为其设置请求方法和url

通过 设置请求头

然后发送请求,post传递参数放入send()内

接着对其进行事件绑定onreadystetechange,处理服务端返回的结果;

首先判断是否等于4,即服务端返回了所有结果状态,

若等于4则在判断响应状态是否为200,即正确响应

在将响应的信息通过innerHTML添加到盒子内

  1. <script>
  2. const result = ('.result')
  3. ('mouseover', function () {
  4. // 1.创建对象
  5. const xhr = new XMLHttpRequest()
  6. //2。初始化,设置请求类型和url
  7. xhr.open('POST', 'http://127.0.0.1:8000/server');
  8. // 设置请求头 Content-Type设置请求体类型,也可以自己定义但会报错
  9. // application/x-www-form-urlencoded参数查询字符串固定写法
  10. ('Content-Type', 'application/x-www-form-urlencoded')
  11. // 3.发送
  12. //post请求设置参数
  13. xhr.send('a=100&b=200&c=300');
  14. // 4.事件绑定 处理服务端返回的结果
  15. = function () {
  16. if ( === 4) {
  17. if (xhr.status >= 200 && xhr.status < 300) {
  18. =
  19. }
  20. }
  21. }
  22. })
  23. </script>

然后在内添加post路由规则

  1. // 1.引入express
  2. const express = require('express')
  3. // 2.创建应用对象
  4. const app = express()
  5. // 3.创建get路由规则
  6. app.get('/server', (request, response) => {
  7. //设置响应头 设置允许跨域
  8. ('Access-Control-Allow-Origin', '*');
  9. //设置响应体
  10. response.send('HELLO AJAX')
  11. })
  12. // 3.创建post路由规则 all可以接受任意类型的请求
  13. app.all('/server', (request, response) => {
  14. //设置响应头 设置允许跨域
  15. ('Access-Control-Allow-Origin', '*');
  16. // 设置响应头
  17. ('Access-Control-Allow-Headers', '*');
  18. //设置响应体
  19. response.send('HELLO AJAX POST')
  20. })
  21. // 4.监听端口启动服务
  22. (8000, () => {
  23. ('服务已启动,8000端口监听中。。。。。');
  24. })

响应发送对象数据

当响应一个对象数据时,需要通过()对对象数据进行字符串转换,然后将转换后的字符串添加到响应体

  1. app.all('/json-server', (request, response) => {
  2. //设置响应头 设置允许跨域
  3. ('Access-Control-Allow-Origin', '*');
  4. // 设置响应头
  5. ('Access-Control-Allow-Headers', '*');
  6. // 响应一个数据
  7. const data = {
  8. name: 'lalala'
  9. };
  10. // 对对象数据进行字符串转换
  11. let str = (data)
  12. //设置响应体
  13. response.send(str)
  14. }

当服务器转换结果为字符串时,页面无法识别,所以这时需要将json字符串转换为js对象;有以下方法:

(1)手动对数据进行转化

  1. let data = JSON.parse(xhr.response)
  2. = data.name

(2)通过自动转换

设置响应体数据类型

  = 'json'
  1. console.log(xhr.response);
  2. = xhr.response.name

五.AJAX问题

缓存问题

  1. app.get('/ie', (request, response) => {
  2. //设置响应头 设置允许跨域
  3. ('Access-Control-Allow-Origin', '*');
  4. //设置响应体
  5. response.send('HELLO IE-3')
  6. })

当你响应体改变时,IE不会更新,而是走缓存,还是上一次的响应体;解决方法是在url后面添加时间戳,使每次的url都不一样,这样就不会出现改变响应体时IE走缓存不更新的问题

   xhr.open('GET', 'http://127.0.0.1:8000/ie?t=' + Date.now())//Date.now()获取当前时间戳

2.请求超时与网络异常处理

服务端写个定时函数,三秒后向页面传递响应体

  1. //针对超时响应的
  2. app.get('/delay', (request, response) => {
  3. //设置响应头 设置允许跨域
  4. ('Access-Control-Allow-Origin', '*');
  5. setTimeout(() => {
  6. //设置响应体
  7. response.send('延时响应')
  8. }, 3000)
  9. })

在页面进行超时设置,可以设置超时和超时回调,还有网络异常回调 

  1. // 超时设置 2秒内还没有接受到响应体则取消请求
  2. = 2000
  3. //超时回调
  4. = function () {
  5. alert('网络不太好再等等!')
  6. }
  7. //网络异常回调
  8. = function () {
  9. alert('你的网络似乎出现问题了')
  10. }

手动取消请求

上面通过自动取消请求,下面介绍手动取消请求:

通过()方法取消请求,作用域的问题,把xhr定义在外边给个null,然后赋值xhr实例,再调用方法。(重复赋值不要用const噢,能用const就用const,不能const就let)

  1. <button>点击发送</button>
  2. <button>点击取消</button>
  3. <script>
  4. const btns = ('button')
  5. let xhr = null
  6. btns[0].onclick = function () {
  7. xhr = new XMLHttpRequest();
  8. xhr.open('GET', 'http://127.0.0.1:8000/delay')
  9. xhr.send(); //不用拿响应体,所以后边儿不写了
  10. }
  11. //取消请求,abort方法
  12. btns[1].addEventListener('click', function () {
  13. (); //先点send再点cancel不会报错,先点cancel报错
  14. (xhr); //先点send再点cancel是xhr实例,先点cancel报错
  15. })

4.请求重复发送问题

用户多次点击发送按钮时,判断标识量isSending判断是否正在发送请求,若正在发送,取消此次的请求,创建新请求

不知道为啥()一直报错!!!!!(好像是chrome不支持本地的ajax导致的,换个浏览器好了)

  1. <button>点击发送</button>
  2. <script>
  3. const btns = ('button');
  4. let xhr = null;
  5. //标识变量,判断是否发送AJAX请求
  6. let isSending = false;
  7. btns[0].onclick = function () {
  8. // 判断标识量 如果正在发送请求,则再次点击后取消该请求,创建一个新请求
  9. if (isSending) ()
  10. xhr = new XMLHttpRequest();
  11. isSending = true;
  12. xhr.open('GET', 'http://127.0.0.1:8000/delay')
  13. xhr.send()
  14. = function () {
  15. if ( === 4) {
  16. // 修改标识量 发送完毕后停止发送
  17. isSending = false
  18. }
  19. }
  20. }
  21. </script>