【Ajax】(一)ajax简介、HTTP协议、ajax的准备工作、发送ajax请求、nodemon自动重启工具

一、ajax简介

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

1、XML简介

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

2、ajax的特点

ajax的优点

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

ajax的缺点

(1)没有浏览历史,不能回退
(2)存在啊跨域问题(同源)
(3)SEO不友好

二、HTTP协议

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

重点格式与参数:

1、请求报文

行:POST /URL HTTP 协议版本
头: Host:值 Cookie: 值 Content-type:值 User-Agent:值等等
空行:
体:如果是GET请求体为空,如果是POST可以不为空

2、响应报文

行:HTTP协议版本 响应状态码 响应状态字符串
头: Content-type:值 Content-length:值 Content-encoding:值等等
空行:
体:HTML语法内容

三、ajax的准备工作

1、安装node.js

这一步无脑安装就可以了

2、安装express

打开文件点击终端,输入npm iexpress

3、创建一个服务端

(1)创建一个JS文件,编写四个步骤,然后在终端输入node 文件名.js 就可以启动服务

//1. 引入express
const express = require('express');

//2. 创建应用对象
const app = express();

//3. 创建路由规则
// request  是对请求报文的封装
// response 是对响应报文的封装
app.get('/', (request, response) => {
    //设置响应
    response.send('HELLO EXPRESS');
});

//4. 监听端口启动服务
app.listen(8000, () => {
    console.log("服务已经启动, 8000端口监听中....");
});

在这里插入图片描述
(2)然后就可以在网站上输入本机地址:8000进行访问
在这里插入图片描述
(3)端口释放:Ctrl+C

四、发送Ajax请求

1、发送GET请求

要编写两个文件,一个是前端页面的准备,一个是服务端代码的准备

前端我们设置一个按钮,点击按钮可以发送ajax请求给服务器,把请求体放到div里

<body>
    <button>点击发送请求</button>
    <div id="result"></div>
</body>
//获取button元素
        const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");
        //绑定事件
        btn.onclick = function () {
            //1. 创建对象
            const xhr = new XMLHttpRequest();
            //2. 初始化 设置请求方法和url
            xhr.open('GET', 'http://192.168.0.102:8000/server');
            //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) {
                        // 处理结果    行  头 空行 体
                        //响应
                        console.log('状态码:' + xhr.status);// 状态码
                        console.log('状态字符串:' + xhr.statusText);// 状态字符串
                        console.log('所有响应头:' + xhr.getAllResponseHeaders());//所有响应头
                        console.log('响应体:' + xhr.response);//响应体

                        // 设置 result 的文本
                        result.innerHTML = xhr.response;
                    }
                }
            }

        }

服务端server.js文件:

//1. 引入express
const express = require('express');

//2. 创建应用对象
const app = express();

//3. 创建路由规则
// request  是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response) => {
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');

    //设置响应体
    response.send('HELLO Ajax');
});

//4. 监听端口启动服务
app.listen(8000, () => {
    console.log("服务已经启动, 8000端口监听中....");
});

2、发送POST请求

POST请求这里跟GET请求不同的是,设置参数是在send方法里面设置的,可以是任意类型

const result = document.querySelector('#result');
result.addEventListener('mouseover' ,function() {
   //1.创建对象
   const xhr = new XMLHttpRequest();
   //2.初始化 设置类型与url
   xhr.open('POST','http://127.0.0.1:8000/server');
   //设置请求头:固定写法,第一个参数设置请求体内容类型,第二个参数是参数查询字符串的类型
   xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); 
   //3.发送请求,在这里传参,任意类型都可以
   xhr.send('a=1&b=2&c=3');
   // xhr.send('12241312312');
   //4.绑定事件
   xhr.onreadystatechange = function() {
       //判断服务端是否返回所有结果
       if(xhr.readyState === 4) {
           //判断响应是否成功
           if(xhr.status >=200 && xhr.status<300) {
               //处理服务端返回的结果
               result.innerHTML = xhr.response;
           }
       }
   }
})

服务端server.js是要设置post请求

//1. 引入express
const express = require('express');

//2. 创建应用对象
const app = express();

//3. 创建路由规则
// request  是对请求报文的封装
// response 是对响应报文的封装
app.post('/server', (request, response) => {
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');

    //设置响应体
    response.send('HELLO Ajax');
});

//4. 监听端口启动服务
app.listen(8000, () => {
    console.log("服务已经启动, 8000端口监听中....");
});

##/3、设置请求头信息
open方法后面,send方法前,添加xhr.setRequestHeader()方法

xhr.open('GET', 'http://192.168.0.102:8000/server');
//设置请求头
xhr.setRequestHeader('Content-Type','application/x-ww-form-urlencoded');
//3. 发送
xhr.send();

3、响应JSON数据

假设服务端server.js有一个data数据,因为send方法里面只能接收字符串,所以我们要对data数据进行字符串转换

app.all('/json-server', (request, response) => {
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应数据
    const data = {
        name: '你好zh'
    };
    let str = JSON.stringify(data);
    //设置响应体
    response.send(str);
});

页面文件我们设置一个

const result = document.getElementById("result");
        //绑定键盘按下事件
        window.onkeydown = function () {
            //1. 创建对象
            const xhr = new XMLHttpRequest();
            //2. 初始化 设置请求方法和url
            xhr.open('GET', 'http://192.168.0.102:8000/json-server');
            //3. 发送
            xhr.send();
            // 事件绑定
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        console.log(xhr.response);
                        result.innerHTML = xhr.response; 
                    }
                }
            }
        }

在这里插入图片描述
我们可以看到已经拿到了这个data数据,但是它还是一个JSON格式的字符串,现在我们要把它提取出来,一共有两种方法:
(1)手动对数据进行转换

xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        // console.log(xhr.response);
                        // result.innerHTML = xhr.response; 
                        let data = JSON.parse(xhr.response);
                        console.log(data);
                        result.innerHTML = data.name;
                    }
                }
            }

(2)自动转换

const result = document.getElementById("result");
        window.onkeydown = function () {
            const xhr = new XMLHttpRequest();
            // 设置响应体数据的类型
            xhr.responseType = 'json';
            xhr.open('GET', 'http://192.168.0.102:8000/json-server');
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        result.innerHTML = xhr.response.name;
                    }
                }
            }
        }

在这里插入图片描述

4、Ajax请求存在的问题

(1)IE缓存问题

在IE浏览器中,他不会随着响应体的更新而更新,解决的方法就是在url后面加一个时间戳,让他知道这是不同时间发送的不同的响应体,这样问题就解决了

const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");
        //绑定键盘按下事件
        btn.addEventListener('click', function () {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', 'http://192.168.0.102:8000/ie' + Date.now());
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        result.innerHTML = xhr.response;
                    }
                }
            }
        })

服务端server.js

app.get('/ie', (request, response) => {
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.send('hello ie -1');
});
//4. 监听端口启动服务
app.listen(8000, () => {
    console.log("服务已经启动, 8000端口监听中....");
});

(2)Ajax请求超时与网络异常处理

在服务端写一个延时器,等过两秒在发送响应体

app.get('/delay', (request, response) => {
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    setTimeout(() => {
        response.send('演示响应');
    }, 3000)
});

设置超时xhr.timeout,超时回调xhr.ontimeout,网络异常回调xhr.onerror

const xhr = new XMLHttpRequest();
//超时设置 2s 设置
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){
      alert("网络异常,请稍后再试!!");
}
// 网络异常回调
xhr.onerror = function(){
      alert("你的网络似乎除了一些问题!");
}

怎么体现出网络异常回调呢?
我们可以用浏览器中的手动断网
在这里插入图片描述

(3)Ajax取消请求

还是在服务端设置延时器

app.get('/delay', (request, response) => {
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    setTimeout(() => {
        response.send('演示响应');
    }, 3000)
});

设置两个按钮

<button>点击发送</button>
<button>点击取消</button>

abort()方法设置取消请求

const btns = document.querySelectorAll('button');

let x = null;
btns[0].onclick = function () {
     x = new XMLHttpRequest();
     x.open("GET", "http://192.168.0.102:8000/delay");
     x.send();
}

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

(3)Ajax重复请求

当重复点击发送ajax请求时,服务器的压力会很大,解决的办法就是定义一个标识变量,设置为false,当点击了发送ajax请求时,把标识变量设置为true,当readyState等于4的时候,再把标识变量变回true

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://192.168.0.102:8000/delay");
     x.send();
     x.onreadystatechange = function () {
         if (x.readyState === 4) {
         // 修改标识变量
         isSending = false;
         }
     }
}

在这里插入图片描述

五、nodemon自动重启工具

当我们每一次修改服务端代码时,总是要执行node 文件名.js命令来重启,安装nodemon工具就可以去掉这个操作,它会自动重启服务,非常的便捷
在终端先执行npm install -g nodemon,然后执行nodemon server.js命令安装nodemon即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值