️️一篇快速上手 AJAX 异步前后端交互

news2024/11/18 17:33:34

AJAX

  • 1. AJAX
    • 1.1 AJAX 简介
    • 1.2 AJAX 优缺点
    • 1.3 AJAX 前后端准备
    • 1.4 AJAX 请求基本操作
    • 1.5 AJAX 发送 POST 请求
    • 1.6 设置请求头
    • 1.7 响应 JSON 数据
    • 1.8 AJAX 请求超时与网络异常处理
    • 1.9 取消请求
    • 1.10 Fetch 发送 Ajax 请求
  • 2. jQuery-Ajax
    • 2.1 jQuery 发送 Ajax 请求(GET和POST)
    • 2.2 jQuery 通用方法发送 Ajax 请求
  • 3. Axios-Ajax
    • 3.1 Axios 发送 Ajax 请求(GET和POST)
    • 3.2 Axios 函数发送 Ajax 请求
  • 4. 跨域
    • 4.1 同源策略
    • 4.2 如何解决跨域
      • 4.2.1 JSONP
      • 4.2.2 CORS

1. AJAX

1.1 AJAX 简介

AJAX 全名 Asynchronous Javascript and XML(异步 JavaScript 和 XML)

  • AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

  • 通过 AJAX 可以在浏览器中向服务器发送异步请求,可以实现 无刷新获取数据。

应用场景:

在这里插入图片描述

1.2 AJAX 优缺点

✅ 可以无需刷新页面而与服务器端进行通信。

✅ 允许你根据用户事件(鼠标事件、键盘事件、表单事件…)来更新部分页面内容。


❎ 没有浏览历史,不能回退。

❎ 存在跨域问题

❎ SEO 不友好,AJAX的内容是动态创建到页面当中去,不好爬取代码。

1.3 AJAX 前后端准备

使用 nodejs 作为服务端,与 html 页面交互

在这里插入图片描述

GET.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AJAX GET 请求</title>
    <style>
        #result{
            width: 200px;
            height: 100px;
            border: solid 1px red;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
</body>
</html>

server.js

const express = require("express");

const app = express();

// 路由规则
app.get("/server", (request, response) => {
  // 设置响应头,允许跨域
  response.setHeader("Access-Controll-Allow-Origin", "*");
  // 设置响应体
  response.send("Hello AJAX");
});

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

1.4 AJAX 请求基本操作

点击按钮向服务端发送 AJAX 请求,响应结果到 div 中

发送 AJAX 请求操作:

<script>
    const btn = document.getElementsByTagName("button")[0];
btn.onclick = function () {
    // 1.创建对象
    const xhr = new XMLHttpRequest();
    // 2.初始化, 设置请求方法和url
    xhr.open("GET", "http://127.0.0.1:8000/server");
    // 3.发送
    xhr.send();
    // 4.事件绑定 处理服务端返回的结果
    // readyState: 0-未初始化 1-open方法调用完毕 2-send方法调用完毕 3-服务端返回了部分结果 4-服务端返回了所有结果
    xhr.onreadystatechange = function () {
        // 判断服务端是否返回了所有结果
        if (xhr.readyState === 4) {
            // 判断是否响应成功 2xx
            if (xhr.status >= 200 && xhr.status < 300) {
                console.log(xhr.status); // 状态码
                console.log(xhr.statusText); // 状态字符串
                console.log(xhr.getAllResponseHeaders()); // 所有响应头
                console.log(xhr.response); // 响应体
            } else {
            }
        }
    };
};
</script>

AJAX 请求成功

返回响应结果到页面中

<script>
    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://127.0.0.1:8000/server");
    // 3.发送
    xhr.send();
    // 4.事件绑定 处理服务端返回的结果
    // readyState: 0-未初始化 1-open方法调用完毕 2-send方法调用完毕 3-服务端返回了部分结果 4-服务端返回了所有结果
    xhr.onreadystatechange = function () {
        // 判断服务端是否返回了所有结果
        if (xhr.readyState === 4) {
            // 判断是否响应成功 2xx
            if (xhr.status >= 200 && xhr.status < 300) {
                result.innerHTML = xhr.response;
            } else {
            }
        }
    };
};
</script>

在这里插入图片描述

1.5 AJAX 发送 POST 请求

鼠标移入 div 时向服务端发请求,然后把响应体结果放入 div 中呈现

AJAX 发送 POST 请求

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 (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
                result.innerHTML = xhr.response;
            }
        }
    };
});

nodejs 添加对应的路由规则

app.post("/server", (request, response) => {
    // 设置响应头,允许跨域
    response.setHeader("Access-Control-Allow-Origin", "*");
    // 设置响应体
    response.send("Hello AJAX POST");
});

在这里插入图片描述

附带请求参数

xhr.send("a=199&b=1");

1.6 设置请求头

在这里插入图片描述

由于使用了自定义头,浏览器安全机制会阻止发送请求

在这里插入图片描述

在 nodejs 中设置放行所有头信息

放行之后仍然不行,因为还会发送一个 OPTIONS 的请求做一个头信息校验,这时没有匹配的路由规则所以无法成功。

在这里插入图片描述

路由规则设置为 all 可以接受任意类型的请求即可

20241111114815583

1.7 响应 JSON 数据

nodejs:

app.all("/json-server", (request, response) => {
    // 设置响应头,允许跨域
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Headers", "*");

    const data = {
        name: "Fetters"
    };

    let str = JSON.stringify(data)

    // 设置响应体
    response.send(str);
  });	

1️⃣ 手动数据转换

const result = document.getElementById("result");
result.addEventListener("mouseover", function () {
    const xhr = new XMLHttpRequest();
    xhr.open("POST", "http://127.0.0.1:8000/json-server");
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
                // 手动对数据转换
                let data = JSON.parse(xhr.response);
                result.innerHTML = data;
            }
        }
    };
});

2️⃣ 设置响应体类型自动转换

const result = document.getElementById("result");
result.addEventListener("mouseover", function () {
    const xhr = new XMLHttpRequest();

    // 设置响应体数据的类型
    xhr.responseType = "json";

    xhr.open("POST", "http://127.0.0.1:8000/json-server");
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
                result.innerHTML = xhr.response.name;
            }
        }
    };
});

在这里插入图片描述

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

nodejs:

app.get("/delay", (request, response) => {
  response.setHeader("Access-Control-Allow-Origin", "*");
  setTimeout(() => {
    response.send("延时响应");
  }, 3000);
});

html:

<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
        const btn = document.getElementsByTagName("button")[0];
        const result = document.getElementById("result");

        btn.addEventListener("click", function () {
            const xhr = new XMLHttpRequest();

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

            xhr.open("GET", "http://127.0.0.1:8000/delay");
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        result.innerHTML = xhr.response;
                    }
                }
            };
        });
    </script>
</body>

请求超时:

网络异常:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里插入图片描述

1.9 取消请求

html:

<body>
    <button>点击发送请求</button>
    <button>点击取消请求</button>
    <script>
        const btns = document.querySelectorAll("button");
        let xhr = null;

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

        // abort
        btns[1].onclick = function () {
            xhr.abort();
        };
    </script>
</body>

20241111152758070

1.10 Fetch 发送 Ajax 请求

btn.onclick = function () {
    fetch("http://127.0.0.1:8000/fetch-server?vip=10", {
        // 请求方法
        method: "POST",
        // 请求头
        headers: {
            name: "Fetters",
        },
        // 请求体
        body: "username=admin&password=admin",
    }).then(response => {
        return response.text();
    }).then(data => {
        console.log(data);
    });
};

2. jQuery-Ajax

2.1 jQuery 发送 Ajax 请求(GET和POST)

// GET
$('button').eq(0).click(function() {
    $.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data) {
        console.log(data);
    }, 'json');
});


// POST
$('button').eq(0).click(function() {
    $.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data) {
        console.log(data);
    });
});

2.2 jQuery 通用方法发送 Ajax 请求

$('button').eq(2).click(function() {
    $.ajax({
        // url
        url: 'http://127.0.0.1:8000/jquery-server',
        // 参数
        data: {a: 100, b:200},
        // 请求类型
        type: 'GET',
        // 响应体结果
        dataType: 'json',
        // 成功的回调
        success: function(data) {
            console.log(data);
        },
        // 超时时间
        timeout: 2000,
        // 失败的回调
        error: function() {
            console.log('error!');
        },
        // 头信息
        headers: {
            c: 300,
            d: 400
        }
    });
});

3. Axios-Ajax

在这里插入图片描述

3.1 Axios 发送 Ajax 请求(GET和POST)

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

// 配置 baseURL
axios.defaults.baseURL = "http://127.0.0.1:8000";

btns[0].onclick = function () {
    // GET
    axios.get("/axios-server", {
        // url 参数
        params: {
            id: 100,
            vip: 7,
        },
        // 请求头参数
        headers: {
            name: "Fetters",
            age: 23,
        },
    }).then(value => console.log(value));
};

btns[1].onclick = function () {
    // POST
    axios.post("/axios-server",
        // 请求体
        {
            username: "admin",
            password: "admin",
        },
        {
            // url 参数
            params: {
                id: 100,
                vip: 7,
            },
            // 请求头参数
            headers: {
                name: "Fetters",
                age: 23,
            },
        }
    ).then(value => console.log(value));
};

3.2 Axios 函数发送 Ajax 请求

btns[2].onclick = function () {
    axios({
        // 请求方法
        method: "POST",
        // url
        url: "/axios-server",
        // url 参数
        params: {
            vip: 10,
            level: 20,
        },
        // 头信息
        headers: {
            a: 100,
            b: 200,
        },
        // 请求体参数
        data: {
            username: "admin",
            password: "admin",
        },
    }).then(response => {
        console.log(response);
    });
};

4. 跨域

4.1 同源策略

同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略。

同源:协议、域名、端口号 必须完全相同

违背同源策略就是跨域

4.2 如何解决跨域

4.2.1 JSONP

  1. JSONP是什么

    JSONP (JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持 get 请求

  2. JSONP 怎么工作的?

    在网页有一些标签天生具有跨域能力,比如:img, link, iframe, script。

    JSONP就是利用 script 标签的跨域能力来发送请求的。

  3. JSONP的使用

    • 获取客户端发送过来的回调函数的名字

    • 得到要通过JSONP形式发送给客户端的数据

    • 根据前两步得到的数据,拼接出一一个函数调用的字符串

    • 把上一步拼接得到的字符串,响应给客户端的``标签进行解析执行

    🎗️ node服务器端代码

    const express = require('express')
    const app = express()
    const port = 3000
    
    //路由配置
    app.get("/user",(req,res)=>{
        //1.获取客户端发送过来的回调函数的名字
        let fnName = req.query.callback;
        //2.得到要通过JSONP形式发送给客户端的数据
        const data = {name:'tom'}
        //3.根据前两步得到的数据,拼接出个函数调用的字符串
        let result = `${fnName}({name:"tom"})`
        //4.把上步拼接得到的字符串,响应给客户端的<script> 标签进行解析执行
        res.send(result);
    })
    
    app.listen(port, () => {
        console.log(`Example app listening on port ${port}`)
    })
    
    

    🎗️ 前端代码

    <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>JSONP简单实现</title>
    </head>
    <body>
        <button id="btn">点击发送请求</button>
        <script>
            function getJsonpData(data) {
                console.log("获取数据成功")
                console.log(data) //{name:'tom'}
            }
            var btn = document.getElementById("btn");
            btn.onclick = function () {
                //创建script标签
                var script = document.createElement("script");
                script.src = 'http://localhost:3000/user?callback=getJsonpData';
                document.body.appendChild(script);
                script.onload = function () {
                    document.body.removeChild(script)
                }
            }
        </script>
    </body>
    </html>
    

4.2.2 CORS

推荐文章

  • http://www.ruanyifeng.com/blog/2016/04/cors.html
  • https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
  1. CORS (Cross-Origin Resource Sharing), 跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 等请求。跨域资源共享标准新增了一组 HTTP 首部字段(响应头),允许服务器声明哪些源站通过浏览器有权限访问哪些资源

  2. CORS怎么工作的?

    CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行

  3. CORS 的使用

    // 设置响应头,允许跨域
    response.setHeader("Access-Control-Allow-Origin", "*");
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2242937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年11月16日 星期六 重新整理Go技术

今日格言 坚持每天进步一点点~ 一个人也可以是一个团队~ 学习全栈开发, 做自己喜欢的产品~~ 简介 大家好, 我是张大鹏, 今天是2024年11月16日星期六, 很高兴在这里给大家分享技术. 今天又是休息的一天, 做了很多的思考, 整理了自己掌握的技术, 比如Java, Python, Golang,…

炼码LintCode--数据库题库(级别:简单;数量:55道)--刷题笔记_02

目录 炼码LintCode--数据库题库&#xff08;级别&#xff1a;简单&#xff1b;数量&#xff1a;55道&#xff09;--刷题笔记_023618 耗时前三的任务&#xff08;日期差&#xff09;题&#xff1a;sql&#xff1a;解释&#xff1a;DATEDIFF 天数差order by 别名TIMESTAMPDIFF 月…

洛谷刷题日记||基础篇8

#include <iostream> #include <vector> using namespace std;int N, M; // N为行数&#xff0c;M为列数 vector<vector<char>> field; // 表示田地的网格&#xff0c;每个元素是W或. vector<vector<bool>> visited; // 用来记录网格是否访…

在Ubuntu22.04上源码构建ROS noetic环境

Ubuntu22.04上源码构建ROS noetic 起因准备环境创建工作目录并下载源码安装编译依赖包安装ros_comm和rosconsole包的两个补丁并修改pluginlib包的CMakeLists的编译器版本编译安装ROS noetic和ros_test验证 起因 最近在研究VINS-Mono从ROS移植到ROS2&#xff0c;发现在编写feat…

从dos上传shell脚本文件到Linux、麒麟执行报错“/bin/bash^M:解释器错误:没有那个文件或目录”

[rootkylin tmp]#./online_update_wars-1.3.0.sh ba51:./online_update_wars-1.3.0.sh:/bin/bash^M:解释器错误:没有那个文件或目录 使用scp命令上传文件到麒麟系统&#xff0c;执行shell脚本时报错 “/bin/bash^M:解释器错误:没有那个文件或目录” 解决方法&#xff1a; 执行…

react+hook+vite项目使用eletron打包成桌面应用+可以热更新

使用Hooks-Admin的架构 Hooks-Admin: &#x1f680;&#x1f680;&#x1f680; Hooks Admin&#xff0c;基于 React18、React-Router V6、React-Hooks、Redux、TypeScript、Vite2、Ant-Design 开源的一套后台管理框架。https://gitee.com/HalseySpicy/Hooks-Adminexe桌面应用…

华东师范大学数学分析第五版PDF习题答案上册及下册

“数学分析”是数学专业最重要的一门基础课程&#xff0c;也是报考数学类专业硕士研究生的专业考试科目。为了帮助、指导广大读者学好这门课程&#xff0c;编者编写了与华东师范大学数学科学学院主编的《数学分析》(第五版)配套的辅导用书&#xff0c;以帮助读者加深对基本概念…

FineBI漏斗图分析转化率计算,需要获取当前节点和上一节点的转化率,需要获取错行值实现方案

FineBI漏斗图分析转化率计算&#xff0c;当前节点和上一节点的转化率&#xff0c;需要获取错行值 下面这张图大家很熟悉吧&#xff0c;非常经典的漏斗转化率分析。 从漏斗图看到需要计算转化率&#xff0c;都需要获取上一步漏斗的值&#xff0c;比如计算上一个省份的门店数量…

Solana 区块链的技术解析及未来展望 #dapp开发#公链搭建

随着区块链技术的不断发展和应用场景的扩展&#xff0c;性能和可拓展性成为各大公链竞争的关键因素。Solana&#xff08;SOL&#xff09;因其高吞吐量、低延迟和低成本的技术特性&#xff0c;在众多区块链项目中脱颖而出&#xff0c;被誉为“以太坊杀手”之一。本文将从技术层面…

FPGA开发-逻辑分析仪的应用-数字频率计的设计

目录 逻辑分析仪的应用 数字频率计的设计 -基于原理图方法 主控电路设计 分频器设计 顶层电路设计 数字系统开发不但需要进行仿真分析&#xff0c;更重要的是需要进行实际测试。 逻辑分析仪的应用 测试方式&#xff1a;&#xff08;1&#xff09;传统的测试方式&#…

基于python Django的boss直聘数据采集与分析预测系统,爬虫可以在线采集,实时动态显示爬取数据,预测基于技能匹配的预测模型

本系统是基于Python Django框架构建的“Boss直聘”数据采集与分析预测系统&#xff0c;旨在通过技能匹配的方式对招聘信息进行分析与预测&#xff0c;帮助求职者根据自身技能找到最合适的职位&#xff0c;同时为招聘方提供更精准的候选人推荐。系统的核心预测模型基于职位需求技…

kubesphere环境-本地Harbor仓库+k8s集群(单master 多master)+Prometheus监控平台部署

前言&#xff1a;半月前在公司生产环境上离线部署了k8s集群Victoria Metrics(二开版)自研版夜莺 监控平台的搭建&#xff0c;下面我租用3台华为云服务器演示部署kubesphere环境-本地Harbor仓库k8s集群&#xff08;单master节点 & 单master节点&#xff09;Prometheus监控部…

车载诊断框架 --- UDS小白入门篇

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…

强大的正则表达式——Easy

进入题目界面输入难度1后&#xff0c;让我们输入正则表达式&#xff08;regex&#xff09;&#xff1a; 目前不清楚题目要求&#xff0c;先去下载附件查看情况&#xff1a; import re import random# pip install libscrc import libscrcallowed_chars "0123456789()|*&q…

字节青训-小C的外卖超时判断、小C的排列询问

目录 一、小C的外卖超时判断 问题描述 测试样例 解题思路&#xff1a; 问题理解 数据结构选择 算法步骤 最终代码&#xff1a; 运行结果&#xff1a; 二、小C的排列询问 问题描述 测试样例 最终代码&#xff1a; 运行结果&#xff1a; ​编辑 一、小C的外卖超时判断…

游戏引擎学习第13天

视频参考:https://www.bilibili.com/video/BV1QQUaYMEEz/ 改代码的地方尽量一张图说清楚吧,懒得浪费时间 game.h #pragma once #include <cmath> #include <cstdint> #include <malloc.h>#define internal static // 用于定义内翻译单元内部函数 #…

C++11(五)----lambda表达式

文章目录 lambda表达式 lambda表达式 lambda表达式可以看作一个匿名函数 语法 [capture-list] (parameters) mutable -> return-type { statement } auto func1 [](int a, int b) mutable -> int {return a b; }; *capture-list&#xff1a;捕捉列表。编译器根据[]来 判…

CSS基础知识05(弹性盒子、布局详解,动画,3D转换,calc)

目录 0、弹性盒子、布局 0.1.弹性盒子的基本概念 0.2.弹性盒子的主轴和交叉轴 0.3.弹性盒子的属性 flex-direction row row-reverse column column-reverse flex-wrap nowrap wrap wrap-reverse flex-dirction和flex-wrap的组合简写模式 justify-content flex-s…

【Qt聊天室】客户端实现总结

目录 1. 项目概述 2. 功能实现 2.1 主窗口设计 2.2 功能性窗口 2.3 主界面功能实现 2.4 聊天界面功能实现 2.5 个人信息功能开发 2.6 用户信息界面设置功能 2.7 单聊与群聊 2.8 登录窗口 2.9 消息功能 3. 核心设计逻辑 3.1 核心类 3.2 前后端交互与DataCenter 4…

RK3568平台开发系列讲解(高级字符设备篇)IO 模型引入实验

🚀返回专栏总目录 文章目录 一、IO 的概念二、IO 执行过程三、IO 模型的分类阻塞 IO非阻塞 IOIO 多路复用信号驱动异步 IO沉淀、分享、成长,让自己和他人都能有所收获!😄 一、IO 的概念 IO 是英文 Input 和 Output 的首字母, 代表了输入和输出, 当然这样的描述有一点点…