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

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", "*");
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【星海随笔】ZooKeeper-Mesos

开源的由 Twitter 与 伯克利分校的 Mesos 项目组共同研发设计。 两极调度架构 支持高可用集群&#xff0c;通过ZooKeeper进行选举。 Mesos master 管理着所有的 Mesos slave 守护进程 每个slave运行具体的任务或者服务。 Franework 包括的调度器和执行机两部分 执行器运行在Me…

计算机网络中的域名系统(DNS)及其优化技术

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化技术 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化…

Vulnhub靶场案例渗透[10]- Momentum2

文章目录 一、靶场搭建1. 靶场描述2. 下载靶机环境3. 靶场搭建 二、渗透靶场1. 确定靶机IP2. 探测靶场开放端口及对应服务3. 扫描网络目录结构4. 代码审计5. 反弹shell6. 提权 一、靶场搭建 1. 靶场描述 - Difficulty : medium - Keywords : curl, bash, code reviewThis wor…

如何在 Ubuntu 上安装 Emby 媒体服务器

Emby 是一个开源的媒体服务器解决方案&#xff0c;它能让你整理、流媒体播放和分享你的个人媒体收藏&#xff0c;包括电影、音乐、电视节目和照片。Emby 帮你集中多媒体内容&#xff0c;让你无论在家还是在外都能轻松访问。它还支持转码&#xff0c;让你能够播放各种格式的内容…

java作业项目以及azkaban的操作

参考内容&#xff1a; azkaban简介及azkaban部署、原理和使用介绍 1.在azkaban创建project 2.上传flow文件和project文件的压缩包 flow文件内容: nodes:- name: Testtype: commandconfig:command: java -jar /data/job/mtm-job-0.0.1-SNAPSHOT.jar --spring.profiles.activ…

2024-11-15 Element-ui的tab切换中table自适应宽度无法立即100%的问题

前言 今天在写一个统计图表的时候&#xff0c;将所有的table表格和echarts图表放到一个页面中&#xff0c;这样会在纵向上出现滚动条&#xff0c;上下滑动对用户体验不好&#xff0c;于是改成tab切换的形式 遇到的问题 正如标题所述&#xff0c;elementui在tab中使用table时&…

HarmonyOS 开发环境搭建

HarmonyOS&#xff08;鸿蒙操作系统&#xff09;作为一种面向全场景多设备的智能操作系统&#xff0c;正逐渐在市场上崭露头角。为了进入HarmonyOS生态&#xff0c;开发者需要搭建一个高效的开发环境。本文将详细介绍如何搭建HarmonyOS开发环境&#xff0c;特别是如何安装和配置…

Vue全栈开发旅游网项目(10)-用户管理后端接口开发

1.异步用户登录\登出接口开发 1.设计公共响应数据类型 文件地址&#xff1a;utils/response404.py from django.http import JsonResponseclass BadRequestJsonResponse(JsonResponse):status_code 400def __init__(self, err_list, *args, **kwargs):data {"error_c…

快速了解Memcached

快速了解Memcached 官方定义 Memcached 是一个高性能的分布式内存对象缓存系统&#xff0c;用于减轻数据库负载&#xff0c;通过在内存中缓存数据和对象来提高动态 web 应用程序的响应速度。 主要特点 简单高效&#xff1a;其设计理念就是简单&#xff0c;易于部署和使用。它是…

【Android、IOS、Flutter、鸿蒙、ReactNative 】启动页

Android 设置启动页 自定义 splash.xml 通过themes.xml配置启动页背景图 IOS 设置启动页 LaunchScreen.storyboard 设置为启动页 storyboard页面绘制 Assets.xcassets 目录下导入图片 AppLogo Flutter 设置启动页 Flutter Android 设置启动页 自定义 launch_background.xm…

【插件】多断言 插件pytest-assume

背景 assert 断言一旦失败&#xff0c;后续的断言不能被执行 有个插件&#xff0c;pytest-assume的插件&#xff0c;可以提供多断言的方式 安装 pip3 install pytest-assume用法 pytest.assume(表达式,f’提示message’) pytest.assume(表达式,f‘提示message’) pytest.ass…

DDRPHY数字IC后端设计实现系列专题之数字后端floorplanpowerplan设计

3.2.3 特殊单元的布局 布图阶段除了布置 I/O 单元和宏单元&#xff0c;在 28nm 制程工艺时&#xff0c;还需要处理两种特 殊的物理单元&#xff0c;Endcap 和 Tapcell。 DDRPHY数字IC后端设计实现系列专题之后端设计导入&#xff0c;IO Ring设计 &#xff08;1&#xff09;拐…

Java 全栈知识体系

包含: Java 基础, Java 部分源码, JVM, Spring, Spring Boot, Spring Cloud, 数据库原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分布式, 中间件, 开发工具, Git, IDE, 源码阅读&#xff0c;读书笔记, 开源项目...

【Docker系列】如何在 Docker 环境中部署和运行 One API

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

录的视频怎么消除杂音?从录制到后期的杂音消除攻略

在录制视频时&#xff0c;杂音往往是一个令人头疼的问题。无论是环境噪音、设备噪音还是电磁干扰&#xff0c;杂音的存在都会极大地影响视频的听觉体验。录的视频怎么消除杂音&#xff1f;通过一些前期准备和后期处理技巧&#xff0c;我们可以有效地消除这些杂音&#xff0c;提…

微信小程序:vant组件库安装步骤

前言&#xff1a;在微信小程序中引用vant组件报错&#xff0c;提示路径不存在&#xff0c;这很有可能是因为没有安装构建vant组件库导致。下面是我整理的安装vant组件库的步骤: 第一步&#xff1a;安装node.js(执行完第一步请重启小程序) 具体步骤请看链接&#xff1a;node.js…

蓝桥杯-洛谷刷题-day3(C++)

目录 1.忽略回车的字符串输入 i.getline() ii.逐个字符的识别再输入 2.获取绝对值abs() 3.做题时的误区 4.多个变量的某一个到达判断条件 i.max() 5.[NOIP2016 提高组] 玩具谜题 i.代码 6.逻辑上的圆圈 i.有限个数n的数组 7.数组的定义 i.动态数组 1.忽略回车的字符串输…

Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别

Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别 keyword 与 text 区别term 查询match 查询match_phrase 查询match_phrase_prefix 查询写在最后 在讲述 es 查询时 term、match、match_phrase、match_phrase_prefix 的区别之前&#xff0c;先来了…

Restful API接⼝简介及为什么要进⾏接⼝压测

一、RESTful API简介 在现代Web开发中&#xff0c;RESTful API已经成为一种标准的设计模式&#xff0c;用于构建和交互网络应用程序。本文将详细介绍RESTful API的基本概念、特点以及如何使用它来设计高效的API接口。 1. 基于协议 HTTP 或 HTTPS RESTful API通常使用HTTP&am…

Android Studio 控制台输出的中文显示乱码

1. Android Studio 控制台输出的中文显示乱码 1.1. 问题 安卓在调试阶段&#xff0c;需要查看app运行时的输出信息、出错提示信息。乱码&#xff0c;会极大的阻碍开发者前进的信心&#xff0c;不能及时的根据提示信息定位问题&#xff0c;因此我们需要查看没有乱码的打印信息。…