AJAX(一):初识AJAX、http协议、配置环境、发送AJAX请求、请求时的问题

一、什么是AJAX?

1.原生AJAX

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

2.XML

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

3.AJAX的优缺点

优点:
(1)可以无需刷新页面而与服务器端进行通信。
(2)允许你根据用户事件来更新部分页面内容。
缺点:
(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语法内容

三、准备工作(安装node.js)

1、安装node.js

好像之前安装过(有点早了记不清步骤),后面会整理一下单独发出来。

2、安装express框架

初始化:

在最外层打开终端(右键左栏空白处),输入npm init --yes,之后会自动多出来一个json文件

安装:

输入npm i express

3.使用express框架 

(1)引入

// 1.引入
const { response } = require('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)启动

在终端 => 当前目录下 => 输入node 文件名就可以启动服务.

网页打开,输入127.0.0.1:8000回车 

 

(3)nodemon实现保存自动重启服务


终端运行npm install -g nodemon安装nodemon,这样每次保存就会自动重启服务,比较方便(副作用是所有html都无法保存时自动调整格式),使用时还是在当前目录nodemon+文件名 ,如nodemon server.js(之前是node server.js)

(4)关闭端口

打开终端的node   Ctrl+C就ok

四、发送AJAX请求

1.发送GET请求

点击按钮div中呈现响应体:点击按钮发送AJAX请求给服务器,然后把响应体拿过来放到div中。
没见过这些东西,照着敲的,仔细看我写的注释。

新建一个文件夹

html

<!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>Document</title>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: 1px solid #90b;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
</body>
</html>

js

// 1.引入
const { response } = require('express');
const express = require('express');
// 2.创建应用对象
const app = express();
// 3. 创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
    //设置响应头 设置允许跨域
    response.setHeader('Acess-Control-Allow-Origin','*');
    // 设置响应体
    response.send('HELLO AJAX');
});
// 4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动, 8000端口 监听中......");
})

右键这个文件夹,选择打开终端,记得释放之前的终端node 因为这个端口也是8000

之后在浏览器打开127.0.0.1:8000/server

 

 

再把html改成

<!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>Document</title>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: 1px solid #90b;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
        //获取button元素
            const btn = document.querySelector('button');
            const result = document.querySelector('#result');
            btn.addEventListener('click', function () {
                //1.创建对象
                const xhr = new XMLHttpRequest();
                //2.初始化,设置请求的方法和url
                xhr.open('GET', 'Access-Control-Allow-Origin:http://127.0.0.1:8000/server');
                //3.发送
                xhr.send();

                //4.事件绑定,处理服务端返回的结果
                //on 当……的时候
                //readyState是xhr对象中的属性,表示状态0 1 2 3 4 
                //其中0-未初始化 1-open调用完毕 2-send调用完毕 3-服务端返回了部分结果 4-服务端返回了所有结果
                //change 改变
                xhr.onreadystatechange = function () {
                    //判断服务端是否返回了所有结果
                    if (xhr.readyState === 4) {
                        //判断响应状态码 200 404 403 401 500
                        // 2xx ,2开头都表示成功
                        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;
                        }
                    }
                }
            })

    </script>
</body>
</html>

设置url参数:用?隔开,=赋值,&分隔
例如:http://127.0.0.1:8000/server?a=1&b=2&c=3

2.发送POST请求

鼠标经过div发送AJAX请求,然后拿回来响应体放在div中

<div id="result"></div>

仔细对比GET和POST的不同,好像这个传参在send中写,类型随便??
还有就是可以xhr.setRequestHeader设置请求头,仔细看看注释

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('a:1&b:2&c:3'); 
   // xhr.send('1232142412421312');
   //4.绑定事件
   xhr.onreadystatechange = function() {
       //判断服务端是否返回所有结果
       if(xhr.readyState === 4) {
           //判断响应是否成功
           if(xhr.status >=200 && xhr.status<300) {
               //处理服务端返回的结果
               result.innerHTML = xhr.response;
           }
       }
   }
})

server.js 

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

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

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

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

 

3.JSON响应

服务端响应体也可以设置为一个数据发送过去,但是不能直接写,要通过JSON.stringify(数据)把数据转换为JSON字符串

app.get('/json-server', (request, response) => {
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应一个数据
    const data = { name: 'ht' };
    let str = JSON.stringify(data); //对对象进行字符串转换
    //设置响应体
    response.send(str);
})

页面在拿到JSON字符串响应体的时候,是无法识别的,所以需要把JSON字符串转换为js对象,有两种方式:

(1)手动把JSON字符串转换为js对象

借助JSON.parse(xhr.response)

let data = JSON.parse(xhr.response);
console.log(data);  //js对象:{ name: 'ht' }
result.innerHTML = data.name;

(2)自动把JSON字符串转换为js对象

借助 xhr.responseType = 'json';

xhr.responseType = 'json';
......
console.log(xhr.response); //js对象:{ name: 'ht' }
result.innerHTML = xhr.response.name;

 

五、AJAX请求的几个问题

1.IE缓存问题

//IE缓存问题
app.get('/ie', (request, response) => {
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    response.send('HELLO IE 666');
})

恶心的IE当你响应体改变时,它不会更新,而是走缓存,想要解决这个问题,就要让每次请求的url都不一样,那么我们在后面传个参数,值为时间戳,就可以解决改变响应体时IE走缓存不更新的问题

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

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


服务端写个定时器,2秒后发送响应体过去

app.get('/delay', (request, response) => {
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    setTimeout(() => {
        response.send('HELLO 我延迟响应啦');
    }, 2000);
})


然后点击按钮发送请求时,可以设置超时xhr.timeout和超时回调xhr.ontimeout,还有网络异常回调xhr.onerror

const xhr = new XMLHttpRequest();
//超时设置,1s还没收到响应体,就取消请求
xhr.timeout = 1000;
//超时回调
xhr.ontimeout = function() {
    alert('请求超时baby!');
}
//网络异常回调
xhr.onerror = function () {
    alert('你的网络似乎开小差了!!'); 
}

谷歌浏览器可以自动断网 

 

3.AJAX手动取消请求

还是搞个定时器发送响应体

app.get('/cancel', (request, response) => {
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    setTimeout(() => {
        response.send('HELLO 我请求被取消了,没法发过去了');
    }, 2000);
})


整俩按钮

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

取消请求,用xhr.abort()方法,abort中文意思是中止
这里边儿有个作用域的问题,解决方法是把xhr定义在外边给个null,然后赋值xhr实例,再调用方法。(重复赋值不要用const噢,能用const就用const,不能const就let,反正别var就中了)

const send = document.querySelectorAll('button')[0];
const cancel = document.querySelectorAll('button')[1];

let xhr = null;
//发送请求
send.onclick = function() {
    xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://127.0.0.1:8000/cancel');
    xhr.send();  //不用拿响应体,所以后边儿不写了
}
//取消请求,abort方法
cancel.addEventListener('click', function() {
    xhr.abort(); //先点send再点cancel不会报错,先点cancel报错
    console.log(xhr);  //先点send再点cancel是xhr实例,先点cancel报错
})


4.AJAX请求重复发送问题


服务端还是用的前面的定时器,这里重复请求写个逻辑,如果没处在请求中,就创建新的请求;如果已经请求了,就废掉,再重新创建请求。具体看代码和注释吧,这块儿听的不是很清晰,先简单了解下,还有啊,作用域回头得补补,这块儿太不熟了

const send = document.querySelector('button');

let xhr = null;
let isSending = false;  //是否正在发送AJAX请求
//发送请求
send.onclick = function() {
    //如果没处在请求中,就创建新的请求;如果已经请求了,就废掉,再重新创建请求
    if(isSending) xhr.abort();    
    xhr = new XMLHttpRequest();
    isSending = true;
    xhr.open('GET', 'http://127.0.0.1:8000/delay');
    xhr.send();
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
            //有可能请求失败,所以这里不用再做判断,只要拿到结果,就算请求完成
            isSending = false;  //拿到服务器的全部结果后,置为false
        }
    }
}

总之这块就是听得迷迷糊糊,还看了其他博主的笔记

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值