不同场景下发送AJAX请求

🧑‍🎓 个人主页:花棉袄

📖 本章内容:不同场景下发送AJAX请求

一、AJAX简介

1.1【AJAX简介】

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

1.2【AJAX特点】

💟 AJAX 的优点

  • 🌟 可以无需刷新页面而与服务器端进行通信
  • 🌟 允许你根据用户事件来更新部分页面内容

💟 AJAX 的缺点

  • 🌟 没有浏览历史,不能回退
  • 🌟 存在跨域问题(同源)
  • 🌟 SEO(Search Engine Optimization,搜索引擎优化)不友好,爬虫无法爬取

二、HTTP协议

  • ⏰ HTTP(hypertext transport protocol)协议「超文本传输议」
  • ⏰ 协议详细规定了浏览器和万维网服务器之间互相通信的规则

2.1【请求报文】

💟 请求行

  • ⏰ 请求类型:GET/POST/PUT/DELETE/PATCH
  • ⏰ URL 路径:s?ie=utf-8
  • ⏰ HTTP 协议版本:HTTP/1.1

💟 请求头

  • ⏰ Host: atguigu.com
  • ⏰ Cookie: name=guigu
  • ⏰ Content-type: application/x-www-form-urlencoded
  • ⏰ User-Agent: chrome 83
  • ⏰ …

在这里插入图片描述

💟 请求空行:固定格式,必须有

💟 请求体:GET请求,请求体为空;POST请求,请求体可以不为空

  • ⏰ username=admin&password=admin

在这里插入图片描述

2.2【响应报文】

💟 响应行

  • ⏰ HTTP 协议版本:HTTP/1.1
  • ⏰ 响应状态码:200/404/500
  • ⏰ 响应状态字符串:OK/Not Found/Internal Server Error,与响应状态码对应

💟 响应头

  • ⏰ Content-Type: text/html;charset=utf-8
  • ⏰ Content-length: 2048
  • ⏰ Content-encoding: gzip
  • ⏰ …

在这里插入图片描述

💟 响应空行 :固定格式,必须有

💟 响应体

在这里插入图片描述

2.3【状态码】

  • 1xx:Informational(信息性状态码) 请求正在处理
  • 2xx:Success(成功状态码) 请求正常处理完毕
  • 3xx:Redirection(重定向) 需要进行附加操作以完成请求
  • 4xx:Client error(客户端错误) 客户端请求出错
  • 5xx:Server Error(服务器错误) 服务器处理请求出错

2.4【响应状态码】

  • 200 OK 请求成功
  • 302 Found 请求资源的 URL 被暂时修改到 Location 提供的 URL
  • 304 Not Modified 资源未变更
  • 308 Permanent Redirect 永久重定向
  • 400 Bad Request 请求语法有问题,服务器无法识别
  • 401 UnAuthorized 客户端未授权该请求
  • 403 Forbidden 服务器拒绝响应
  • 404 Not Found URL 无效或者 URL 有效但是没有资源
  • 500 Internal Server Error 服务器内部错误
  • 502 Bad Gateway 服务器作为网关使用时,收到上游服务器返回的无效响应
  • 503 Service Unavailable 无法服务,一般发生在因维护而停机或者服务过载
  • 504 Gateway Timeout 网关超时
  • 505 Http Version Not Supported 发出的请求http版本服务器不支持

四、使用Express

💟 安装 Node.js

4.1【使用Express】

# 初始化
npm init --yes
# 安装express框架
npm i express
// 1、引入express
// const express = require('express');
import express from 'express';

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

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

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

💟 键入命令 node js文件名
💟 出现服务已经启动,8000 端口监听中…字样,说明启动成功
💟 我们打开浏览器,访问 http://127.0.0.1:8000,出现Hello Express字样

4.2【简单案例】

<!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>
</head>
<body>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: 1px solid #90b;
        }
    </style>

    <button>点击发送</button>
    <div id="result"></div>
</body>
</html>

4.3【发送 GET 请求】

// 1、引入express
// const express = require('express');
import express from '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 端口监听中...");
});

💟 创建对象

const xhr = new XMLHttpRequest();

💟 初始化

xhr.open('GET', 'http://127.0.0.1:8000/server');

💟 发送

xhr.send();

💟 事件绑定,处理服务器端返回的结果

xhr.onreadystatechange = function () {...}
<!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>AJAX发送Get请求</title>
</head>
<body>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: 1px solid #90b;
        }
    </style>
    <button>点击发送</button>
    <div id="result"></div>
    <script>
        const result = document.getElementById('result');
        const button = document.getElementsByTagName("button")[0];
        button.onclick = function () {
            // 1、创建对象
            const xhr = new XMLHttpRequest();
            // 2、初始化
            xhr.open('GET', 'http://127.0.0.1:8000/server');
            // 3、发送
            xhr.send();
            // 4、事件绑定,处理服务器端返回的结果
            xhr.onreadystatechange = function () {
                // 服务端返回所有结果
                if (this.readyState === 4) {
                    // 2xx 成功
                    if (this.status >= 200 && this.status < 300) {
                        // 状态码、状态字符串
                        console.log("status:" + this.status); // 200
                        console.log("statusText:" + this.statusText); // OK
                        // 响应头
                        console.log("Headers:" + this.getAllResponseHeaders()); // content-length: 13  content-type: text/html; charset=utf-8
                        // 响应体
                        console.log("response:" + this.response); // Hello Express
                        // 将响应体内容设置为文本
                        result.innerHTML = this.response;
                    }
                }
            }
        };
    </script>
</body>
</html>

在这里插入图片描述

💟 GET 设置请求行

xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');

4.4【发送 POST 请求】

// 1、引入express
// const express = require('express');
import express from '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 端口监听中...");
});
    <script>
        const result = document.getElementById('result');
        result.addEventListener('mouseover', function () {
            const xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://127.0.0.1:8000/server');
            xhr.send();
            xhr.onreadystatechange = function () {
                if (this.readyState === 4 && this.status >= 200 && this.status < 300) {
                    result.innerHTML = this.response;
                }
            };
        });
    </script>

在这里插入图片描述

💟 POST 设置请求体

xhr.send('a=100&b=200&c=300');

4.5【设置请求头信息】

💟 设置请求头信息

xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

💟 自定义的请求头

xhr.setRequestHeader('name', 'atguigu');
app.all('/server', (request, response) => {
    // 设置响应头,允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    // 设置响应头,允许任意类型的头信息
    response.setHeader('Access-Control-Allow-Headers', '*');
    // 设置响应体
    response.send('Hello Express');
});

4.6【响应 JSON 数据】

const data = {
    name:'Hello Ajax'
}
let str = JSON.stringify(data);
response.send(str);

在这里插入图片描述

💟 手动转换数据

let response = this.response;
console.log(typeof response); // string
data = JSON.parse(response);
result.innerHTML = data.name;

在这里插入图片描述


五、自动重启工具

💟 官网地址:https://www.npmjs.com/package/nodemon
💟 安装命令npm install -g nodemon
💟 启动命令:nodemon xxx.js替代node xxx.js
💟 优点:修改服务端代码不用每次手动shutdown重启

在这里插入图片描述

5.1【请求超时】

# js文件
setTimeout(() =>{
    response.send('Hello Ajax');
}, 2000);
# html文件
// 设置超时时间
xhr.timeout = 1000;
// 设置超时回调
xhr.ontimeout = () => {
    alert('请求超时!');
};

5.2【网络异常】

# html 文件
// 设置网络异常回调
xhr.onerror = () => {
    alert("网络异常");
};

5.3【手动取消请求】

💟 abort()方法:手动取消请求

const btns = document.getElementsByTagName('button');
const btn1 = btns[0];
const btn2 = btns[1];

let xhr = null;
btn1.addEventListener('click', () => {
    xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://127.0.0.1:8000/server-timeout');
    xhr.send();
});
btn2.addEventListener('click', () => {
    xhr.abort();
});

5.4【请求重复发送】

💟 如果服务器响应相对比较慢,而用户因为得不到响应而频繁地点击按钮
💟 浏览器短时间内会向服务器发起大量重复的请求
💟 服务器就要对这些请求进行频繁的处理
💟 服务器端的压力就会非常的大

const btns = document.getElementsByTagName('button');
let xhr = null;
// 标识是否正在发送 AJAX 请求
let isSending = false;
btns[0].addEventListener('click', () => {
    // 若上一个请求尚未完成,则手动取消请求
    if (isSending) {
        xhr.abort();
    }
    xhr = new XMLHttpRequest();
    isSending = true;
    xhr.open('GET', 'http://127.0.0.1:8000/servertimeout');
    xhr.send();
    xhr.onreadystatechange = () => {
        // 请求响应完毕后,修改变量标识
        if (xhr.readyState === 4) {
            isSending = false;
        }
    };
});

在这里插入图片描述


六、JQuery发送AJAX请求

💟 jQuery 脚本

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

💟 bootstrp 脚本

<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet">

6.1【GET 请求】

$.get(url,[data],[callback],[type])

💟 url:请求的 URL 地址
💟 data:请求携带的参数
💟 callback:载入成功时回调函数
💟 type:设置返回内容格式,xml,html,script,ison,text,_default

btns.eq(0).click(() => {
    $.get('http://127.0.0.1:8000/server-jquery', { a: 100, b: 200 }, (data) => {
        console.log(typeof data, data); // object {name: "Hello jquery"}
    }, 'json');
});

6.2【POST请求】

$.post(url,[data],[callback],[type])

💟 url:请求的 URL 地址
💟 data:请求携带的参数
💟 callback:载入成功时回调函数
💟 type:设置返回内容格式,xml,html,script,ison,text,_default

btns.eq(1).click(() => {
    $.post('http://127.0.0.1:8000/server-jquery', { a: 100, b: 200 }, (data) => {
        console.log(typeof data, data); // string {name: "Hello jquery"}
    },"json");
});

6.3【通用方法】

$.ajax({
    // 请求地址
    url: 'http://127.0.0.1:8000/server-jquery',
    // 请求参数
    data: { a: 100, b: 200 },
    // 请求类型
    type: 'GET',
    // 响应体类型
    dataType: 'json',
    // 成功回调
    success: data => {
        console.log(typeof data, data); // string {name: "Hello jquery"}  开启dataType后:object {name: "Hello jquery"}
    },
    // 超时时间
    timeout: 1000,
    // 失败的回调
    error: () => {
        alert('出错了');
    },
    // 头信息
    headers: {
        c: 300,
        d: 400
    }
});

七、Axios发送AJAX请求

7.1【GET 请求】

 axios.get(url[,config])
  • 函数返回结果是一个promise对象,用then回调处理
axios.defaults.baseURL = 'http://127.0.0.1:8000/';
axios.get('/server-axios', {
    // 请求参数
    params: {
        a: 100,
        b: 200
    },
    // 请求头
    headers: {
        c: 300,
        d: 400
    }
}).then(value => {
    console.log(value);
});

7.2【POST 请求】

axios.post(url[,data[,config]])
axios.post('server-axios', {
    // 请求体
		e: 500,
  		f: 600  
}, {
    // 请求参数
    params: {
        a: 100,
        b: 200
    },
    // 请求头
    headers: {
        c: 300,
        d: 400
    }
}).then(value => {
    console.log(value);
});

7.3【通用方法】

axios(url[, config])
axios({
    method: 'POST',
    url: '/server-axios',
    // 请求参数
    params: {
        a: 100,
        b: 200
    },
    // 请求头
    headers: {
        c: 300,
        d: 400
    },
    // 请求体
    data: {
        e: 500,
        f: 600
    },
    // 响应体类型
    dataType: 'json'
}).then(response => {
    console.log(response.status); // 200
    console.log(response.statusText); // OK
    console.log(response.headers); // {content-length: "22", content-type: "text/html; charset=utf-8"}
    console.log(typeof response.data, response.data); // object {name: "Hello axios"}
});

八、Fetch函数发送AJAX请求

fetch('http://127.0.0.1:8000/server-fetch?a=100&b=100', {
    // 请求方法
    method: 'POST',
    // 请求头
    headers: {
        c: 300,
        d: 400
    },
    // 请求体
    body: 'e=500&f=600'
}).then(response => {
    console.log(response);
});
  • 如果我们只想要响应体内容,可以修改then回调
...
.then(response => {
    return response.text();
}).then(response => {
    console.log(typeof response, response); // string {"name":"Hello fetch"}
});
  • 如果明确响应体内容为 json 字符串,可以按如下修改,将会返回一个 object 对象
...
.then(response => {
    return response.json();
}).then(response => {
    console.log(typeof response, response); // object {"name":"Hello fetch"}
});

九、跨域问题

9.1【同源策略】

  • 同源:协议、域名、端口号必须完全相同,违背同源策略就是跨域

9.2【JSONP的使用】

<!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>
</head>

<body>
    <style>
       
    </style>
    <button>点击发送</button>
    <div id="result"></div>
    用户名:<input type="text" id="username">
    <p></p>
    <script>
        //声明handle函数
        function handle(data) {
            var input = document.querySelector('input');
            input.style.border = "solid 1px #f00";
            //修改p标签的提示文本
            var p = document.querySelector('p');
            p.innerHTML = data.msg;
        }
    </script>
    <script>
        const input = document.querySelector('input');
        input.onblur = () => {
            let username = this.username;
            // 1、创建一个 script 标签
            var script = document.createElement('script');
            // 2、设置 src 属性
            script.src = 'http://127.0.0.1:8000/check-username';
            // 3、将 script 插入文档中
            document.body.appendChild(script);
        };
    </script>
</body>

</html>
// 1、引入express
// const express = require('express');
import express from 'express';

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

// 3、创建路由规则
// request 请求报文的封装
// response 响应报文的封装
app.all('/check-username', (request, response) => {
  const data = {
      exist: 1,
      msg:'用户名已存在'
  };
  let str = JSON.stringify(data);
  response.end(`handle(${str})`); 
});

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

在这里插入图片描述

9.3【JQuery发送JSONP请求】

$.getJSON(url,[data],[fn])

💟 url:发送请求地址
💟 data:待发送 key/value 参数
💟 callback:载入成功时回调函数

<button>点击发送请求</button><br><br>
<div id="result"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
    $('button').eq(0).click(() => {
        $.getJSON('http://127.0.0.1:8000/server-jsonp-jquery?callback=?', data => {
            $('#result').html(data.msg);
        });
    });
</script>
app.all('/server-jsonp-jquery', (request, response) => {
    const data = {
        exist: 1,
        msg:'用户名已存在'
    };
    let str = JSON.stringify(data);
    response.end(`(${str})`);
});
  • 此时并没有任何输出,但是请求参数中自动生成了一个callback的参数
    在这里插入图片描述
// 接收callback参数
var cb = request.query.callback;
response.end(`${cb}(${str})`);

在这里插入图片描述

9.4【跨域资源共享】

  • 我们要想进行跨域请求,必须在服务端返回结果时设置允许跨域的响应头
// 设置响应头,允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');

9.5【响应首部字段】

💟 Access-Control-Allow-Origin 指定了允许访问该资源的外域 URI
💟 Access-Control-Expose-Headers 让服务器把允许浏览器访问的头放入白名单
💟 Access-Control-Max-Age 指定了 preflight 请求的结果能够被缓存多久
💟 Access-Control-Allow-Credentials 是否允许浏览器读取 response 的内容
💟 Access-Control-Allow-Methods 指明了实际请求所允许使用的 HTTP 方法
💟 Access-Control-Allow-Headers 指明了实际请求中允许携带的首部字段

  • 一般使用,允许跨域、带有自定义头部信息、任意方法
response.setHeader("Access-Control-Allow-Origin", "*"); 
response.setHeader("Access-Control-Allow-Headers", "*"); 
response.setHeader("Access-Control-A1low-Method", "*");

🌟如果文章对你有帮助【关注👍点赞❤️收藏⭐】一起努力!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Silence Lamb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值