AJAX 入门笔记

课程地址

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
AJAX 不是新的编程语言,而是一种使用现有标准的新方法
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容
XMLHttpRequest 只是实现 Ajax 的一种方式。

XML

可扩展标记语言,用来存储和传输数据(序列化),其于 HTML 类似,但是 XML 中的标签不是预定义的,而是自定义的

var s1 = {
	name: "daniel",
	age: 18,
	gender: "M"
}

用 XML 表示为:

<student>
	<name>daniel</name>
	<age>18</age>
	<gender>M</gender>
</student>

现在基本被 json 代替:

{
	"name": "daniel",
	"age": "18",
	"gender": "M"
}	

AJAX 的优缺点

优点

  • 可以不刷新页面与服务器进行通信
  • 允许根据用户事件更新部分页面内容

缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题
  • SEO 不友好

HTTP 报文格式

post 请求:
在这里插入图片描述
响应:
在这里插入图片描述

express

npm init --yes	# 初始化工程
npm install express		# 安装 express

AJAX 发送 GET 请求

服务端代码如下:

const express = require('express');
const app = express();

app.get('/server', (request, response) => {
    // 允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.send('hello, world');
});

app.listen(8000, () => {
    console.log("listening on 8000");
})

前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #result{
            width: 200px;
            height: 100px;
            border: solid 2px red;
        }
    </style>
</head>
<body>
    <button>发送请求</button>
    <div id="result"></div>
</body>
<script>
    const btn0 = document.getElementsByTagName('button')[0];
    btn0.onclick = function() {
        // 1. 创建对象
        const xhr = new XMLHttpRequest();
        const result = document.getElementById('result')
        // 2. 初始化
        xhr.open('GET', 'http://127.0.0.1:8000/server');
        // 3. 发送
        xhr.send();
        /* 
            4. 事件绑定,处理服务端返回的结果。state 有如下 5 个值:
            0:未初始化
            1:open 方法调用完毕
            2:send 方法调用完毕
            3:服务端返回了部分结果
            4:服务端返回了全部结果
        */
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) { // 服务端返回了所有结果
                if (xhr.status >= 200 && xhr.status < 300) {
                   result.innerHTML = xhr.response;
                }
            }
        }
    }
</script>
</html>

GET 设置请求参数

查询字符串参数以 ? 开始,以 & 分隔:

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

AJAX 发送 POST 请求

服务端添加处理 post 请求的回调函数:

app.post('/server', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.send('hello, post');
});

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    #result {
        width: 200px;
        height: 100px;
        border: solid 2px red;
    }
</style>
<body>
    <div id="result"></div>
</body>
<script>
    const result = document.getElementById('result');
    result.addEventListener('mouseover', function() {
        // console.log('mouseover');
        const xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://localhost:8000/server');
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    result.innerHTML = xhr.response;
                }
            }
        };
    });
</script>
</html>

POST 设置请求体

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

设置请求头信息

一般将身份参数信息放入请求头

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

服务端代码加入:

app.all('/server', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');	// 允许所有请求头
    response.send('hello, post');
});

服务端响应 JSON 数据

服务端返回一个 json 字符串

app.all('/json-server', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    const data = {
        name: 'daniel'
    };
    response.send(JSON.stringify(data));	// 序列化
});

客户端从 json 字符串中解析出 json 对象:

<script>
    const result = document.getElementById('result');
    window.onkeydown = function() {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost:8000/json-server');
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    //result.innerHTML = xhr.response;
                    let data = JSON.parse(xhr.response);	// 反序列化
                    result.innerHTML = data.name;
                }
            }
        }
    }
</script>

安装 nodemon,在修改服务端代码后能够自动重启 nodejs

npm install -g nodemon

使用 nodemon 启动 nodejs:

nodemon server.js

ie 缓存问题:ie 会缓存 ajax 的请求结果,如果服务端修改了响应内容,ie 不能及时地呈现。解决方法:在请求后面加上时间戳参数,使得每次请求内容都不同

请求超时与网络异常

对 ajax 做超时设置,给用户提醒

服务端设置延时发送响应:

app.all('/timeout', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    setTimeout(() => {  // 延时发送
        response.send('hello, timeout 3s');
    }, 3000);
});

前端代码添加超时和网络异常处理:

<script>
    const btn = document.getElementsByTagName('button')[0];
    const result = document.getElementById('result');
    btn.addEventListener('click', function() {
        // console.log('mouseover');
        const xhr = new XMLHttpRequest();
        xhr.timeout = 2000;		// 给 ajax 设置超时
        xhr.ontimeout = () => { // 超时回调
            alert("timeout!!!");
        }
        xhr.onerror = () => {   // 网络异常回调
            alert("bad network!!!");
        }
        xhr.open('POST', 'http://localhost:8000/timeout');
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    result.innerHTML = xhr.response;
                }
            }
        };
    });
</script>

取消请求

使用 abort() 方法即可:

<body>
    <button>点击发送请求</button>
    <button>点击取消请求</button>
</body>
<script>
    const btn1 = document.getElementsByTagName('button')[0];
    const btn2 = document.getElementsByTagName('button')[1];
    let xhr = null;
    btn1.onclick = function() {
        xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost:8000/timeout');
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    console.log(xhr.response);
                }
            }
        };
    };
    btn2.onclick = function () {
        xhr.abort();
    }
</script>

重复发送请求问题

设置标志变量,判断是否重复发送:

<script>
    const btn0 = document.getElementsByTagName('button')[0];
    const btn1 = document.getElementsByTagName('button')[1];
    let xhr = null;
    let isSending = false;
    btn0.onclick = function() {
        if (isSending) {
            xhr.abort();
        }
        xhr = new XMLHttpRequest();
        isSending = true;
        xhr.open('GET', 'http://localhost:8000/timeout');
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                isSending = false;  // 请求发送完成
                if (xhr.status >= 200 && xhr.status < 300) {
                    console.log(xhr.response);
                }
            }
        };
    };
    btn1.onclick = function () {
        xhr.abort();
    }
</script>

jQuery 发送 AJAX 请求

get/post 方法

服务端:

app.all('/jquery-server', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    const data = {name: "daniel"}
    response.send(JSON.stringify(data));
});

前端:

<body>
    <div class="container">
        <h2 class="page-header">jQuery 发送 AJAX 请求</h2>
        <button class="btn btn-primary">GET</button>
        <button class="btn btn-danger">POST</button>
        <button class="btn btn-info">通用型方法 ajax</button>
    </div>
</body>
<script>
    $('button').eq(0).click(function() {
        $.get('http://localhost:8000/jquery-server', {a: 100, b: 200}, function(data) {
            console.log(data);
        }, 'json');     // 响应体是一个 json 格式数据,而非普通字符串
    });
    $('button').eq(1).click(function() {
        $.post('http://localhost:8000/jquery-server', {a: 100, b: 200}, function(data) {
            console.log(data);
        });
    });
</script>

通用方法

通用方法可以设置任意 http 请求字段

<script>
    $('button').eq(2).click(function() {
        $.ajax({
            url: 'http://localhost:8000/timeout',
            data: {a: 100, b: 200},
            type: 'GET',
            dataType: 'json',       // 响应体结果
            success: function(data) {
                console.log(data);
            },
            timeout: 2000,
            error: function(data) {
                console.log("error!!!")
            },
            headers: {
                a: 300,
                b: 400
            }
        });
    });
</script>

axios 发送 AJAX 请求

服务端:

const express = require('express');
const app = express();

app.all('/server', (request, response) => {
    // 允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    response.send('hello, world');
});

app.listen(8000, () => {
    console.log("listening on 8000");
})

app.all('/axios-server', (request, response) => {
    // 允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    const data = {name: 'daniel'};
    response.send(JSON.stringify(data));
});

前端:

<body>
    <button>GET</button>
    <button>POST</button>
    <button>AJAX</button>
</body>
<script>
    const btns = document.querySelectorAll('button');
    axios.defaults.baseURL = 'http://localhost:8000';
    btns[0].onclick = function() {
        axios.get('/axios-server', {
            params: {
                id: 100,
                vip: 7
            },
            headers: {
                name: 'daniel',
                age: 18
            }
        }).then(value => {
            console.log(value);
        });
    }
    btns[1].onclick = function() {
        axios.post('axios-server', {
                username: 'admin',
                password: '123456'
            }, {
            params: {
                id: 200,
                vip: 8
            },
            headers: {
                height: 180,
                weight: 80
            }
        });
    }
</script>

axios 函数发送 ajax 请求

函数语法:

// Send a POST request
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

前端代码:

    btns[2].onclick = function() {
        axios({
            method: 'POST',
            url: '/axios-server',
            params: {
                vip: 10,
                level: 30
            },
            headers: {
                a: 100,
                b: 200
            },
            data: {
                username: 'admin',
                password: '123456'
            }
        }).then(response => {
            console.log(response.status);
            console.log(response.statusText);
            console.log(response.headers);
            console.log(response.data);
        });
    }

fetch 函数发送 AJAX 请求

服务端:

app.all('/fetch-server', (request, response) => {
    // 允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    const data = {name: 'daniel'};
    response.send(JSON.stringify(data));
});

前端:

<body>
    <button>ajax</button>
</body>
<script>
    const btn = document.querySelector('button');
    btn.onclick = function() {
        fetch('http://localhost:8000/fetch-server', {
            method: 'POST',
            headers: {
                name: 'daniel'
            },
            body: 'username=admin&password=admin'
        }).then(response => {
            // return response.text();
            return response.json();
        }).then(response => {
            console.log(response);
        });
    }
</script>

同源策略

同源策略是一种安全策略,所谓“同源”就是指协议,域名,端口号完全相同。违背同源策略的行为就是跨域

AJAX 默认是需要遵守同源策略的

多台服务器就存在跨域问题

服务端:

const express = require('express');
const app = express();

app.all('/home', (request, response) => {
    response.sendFile(__dirname + '/home.html');
});

app.all('/data', (request, response) => {
    response.send('userdata');
});

app.listen(9000, () => {
    console.log("listening 9000");
});

前端:

<body>
    <h1>daniel</h1>
    <button onclick="">get userdata</button>
</body>
<script>
    const btn = document.querySelector('button');
    btn.onclick = function() {
        const x = new XMLHttpRequest();
        // 满足同源策略,url 可以简写
        x.open('GET', '/data');
        x.send();
        x.onreadystatechange = function() {
            if (x.readyState === 4) {
                if (x.status >= 200 && x.status < 300) {
                    console.log(x.response);
                }
            }
        }
    }
</script>

JSONP

JSONP 原理

JSON with padding

JSONP 是一个非官方的跨域解决方案,只支持 get 请求

JSONP 利用网页中有一些标签天生具有跨域能力,比如 img link iframe script 等

在前端声明 handle 函数,在 script 中引用:

const data = {
    name: 'daniel'
};

handle(data)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jsonp</title>
    <style>
        #result{
            width: 300px;
            height: 100px;
            border: solid 5px #78a;
        }
    </style>
</head>
<body>
    <div id="result"></div>
    <script>
        function handle(data) {
            const result = document.getElementById('result');
            result.innerHTML = data.name;
        }
    </script>
</body>
<script src="jsonp.js"></script>
</html>

script 中请求到的 js 代码会立即被解释执行

使用 script 标签完成跨域请求:

<script src="http://localhost:8000/jsonp-server"></script>

服务端对应如下规则:

app.all('/jsonp-server', (request, response) => {
    response.send('hello, jsonp-server');
});

响应能够正常返回,但是 console 爆 jsonp-server:1 Uncaught ReferenceError: hello is not defined 错误,原因在于相应内容被当作 js 代码解释执行了

app.all('/jsonp-server', (request, response) => {
    response.send('console.log("hello, jsonp-server")');
});

jsonp:返回一个函数调用语句,其实参就是需要返回的数据,函数的定义在前端,函数的实参在后端传入。服务端代码如下:

app.all('/jsonp-server', (request, response) => {
    const data = {
        name: 'daniel'
    };
    let data_str = JSON.stringify(data);
    response.end(`handle(${data_str})`);
});

JSONP 实践

步骤:

  • 创建 script 标签
  • 设置 src 为跨域目标地址,向服务端请求“js代码”
  • 将 script 添加到 body

前端定义 handle 函数,后端返回一个函数调用的 js 代码,其中的实参由对象的字面量得到

服务端代码:

app.all('/check-username', (request, response) => {
    const data = {
        exist: 1,
        msg: 'username exists'
    };
    let data_str = JSON.stringify(data);
    response.end(`handle(${data_str})`);
});

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>user</title>
</head>
<body>
    用户名:<input type="text" id="username">
    <p></p>
</body>
<script>
    const input = document.querySelector('input');
    const p = document.querySelector('p');
    function handle(data) {
        input.style.border= 'solid 2px #f00'
        p.innerHTML = data.msg;
    }

    input.onblur = function() {
        let uname = this.value;
        const script = document.createElement('script');
        script.src = 'http://localhost:8000/check-username';
        document.body.appendChild(script);
    }
</script>
</html>

jquery 发送 JSONP 请求

前端:

<body>
    <button>jsonp request</button>
    <div id="result"></div>
</body>
<script>
    $('button').eq(0).click(function(){
        $.getJSON('http://localhost:8000/jquery-jsonp-server?callback=?', function(data) {
            $('#result').html(`
                姓名:${data.name},
                校区:${data.city}
            `);
        });
    });
</script>

服务端:

app.all('/jquery-jsonp-server', (request, response) => {
    const data = {
        name: 'daniel',
        city: ['bj', 'sh', 'sz']
    };
    let data_str = JSON.stringify(data);
    let cb = request.query.callback;
    response.end(`${cb}(${data_str})`);
});

CORS

Cross Origin Resource Sharing,跨域资源共享。CORS 是官方的跨域解决方案,它不需要在客户端做任何特殊操作,完全在服务器中进行处理,支持 get 和 post 请求。CORS 标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权访问哪些资源

服务端:

app.all('/cors-server', (request, response) => {
    // 允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.send('hello, cors');
});

前端:

<body>
    <button>cors request</button>
    <div id="result"></div>
</body>
<script>
    const btn = document.querySelector('button');
    btn.onclick = function() {
        const x = new XMLHttpRequest();
        x.open('GET', 'http://localhost:8000/cors-server');
        x.send();
        x.onreadystatechange = function() {
            if (x.readyState === 4) {
                if (x.status >= 200 && x.status < 300) {
                    console.log(x.response);
                }
            }
        };
    }
</script>

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

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

相关文章

NSSCTF第11页(3)

[羊城杯 2020]easyphp 源码 发现会在写入文件之前会删除目录下的除了index.php的文件。写入文件的文件名和文件内容也是可控的&#xff0c;只不过存在过滤 stristr函数对文件内容进行过滤&#xff0c;该函数绕过还是简单的&#xff0c;只需要添加一些特殊字符就可以了&#…

微服务-开篇-个人对微服务的理解

从吃饭说起 个人理解新事物的时候喜欢将天上飞的理念转换成平常生活中的实践&#xff0c;对比理解这些高大上的名词&#xff0c;才能让我们减少恐慌的同时加深理解。废话不多说&#xff0c;我们从吃饭开始说起&#xff0c;逐渐类比出微服务的思想。 &#xff08;个人见解&…

【Git系列】Github指令搜索

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

已解决:KeyError: ‘The truth value of a Series is ambiguous‘ 问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页: &#x1f405;&#x1f43e;猫头虎的博客&#x1f390;《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f996…

「帝国风暴兵」加入 The Sandbox,推出真实的全新人物化身系列和体验!

我们很高兴宣布与流行文化中最具标志性的娱乐品牌 Shepperton 设计工作室的「帝国风暴兵」达成合作伙伴关系。这一合作标志着该科幻品牌首次进入元宇宙&#xff0c;让风暴兵的粉丝们以全新的方式体验「帝国风暴兵」。 在这个体验中&#xff0c;玩家将置身于帝国风暴兵的营地&am…

开发知识点-人工智能-深度学习Tensorflow2.0

Tensorflow 常用的参数有&#xff1a;快捷配置 做得多环境 环境问题 一、 简单 概述二、Tensorflow2版本简介与心得三、深度学习框架安装 Tensorflow2版本安装方法四 、 TF 基础操作So tensor flow 矩阵 在 这个 大框架 流动 五 深度学习要解决的问题六 深度学习应用领域#1下载…

【Mac开发环境搭建】安装HomeBrew、HomeBrew安装Docker、Docker安装Mysql5.7和8

文章目录 HomeBrew安装相关命令安装包卸载包查询可用的包更新所有包更新指定包查看已经安装的包查看包的信息清理包查看brew的版本更新brew获取brew的帮助信息 Brew安装DockerDocker常用命令镜像相关查看已经拉取的所有镜像删除镜像 容器相关停止运行容器启动容器重启容器删除容…

【算法设计】回溯法算法设计——骑士游历问题(C++实现)

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多算法分析与设计知识专栏&#xff1a;算法分析&#x1f525; 给大家跳…

Guli商城-商品服务-API-三级分类-配置网关路由与路径重写

启动人人fast服务&#xff1a; 打开本地的前端项目&#xff0c;启动&#xff1a; 命令&#xff1a;npm run dev 账号密码&#xff1a;admin/admin 对应的数据库&#xff1a; 接下来在商品系统目录中添加子菜单&#xff1a; 数据库中可以看到记录 退出账号&#xff0c;重新登录…

Unity中Shader光照探针的支持

文章目录 前言一、光照探针用在哪怎么用1、光照探针的应用场景2、我们按照以上条件&#xff0c;在Unity中搭建一个相同的环境3、创建光照探针 二、在我们自己的Shader中&#xff0c;实现支持光照探针1、使用常用的 cginc2、在 v2f 中&#xff0c;准备如下变量3、在顶点着色器中…

四川芸鹰蓬飞商务信息咨询有限公司电商服务引领潮流

在今天的数字时代&#xff0c;抖音带货已成为一种新型的、高效的营销方式。许多公司都在寻找可靠的抖音带货服务&#xff0c;以扩大其品牌影响力并增加销售额。在这方面&#xff0c;四川芸鹰蓬飞商务信息咨询有限公司以其专业的知识和经验&#xff0c;成为行业内的佼佼者。 四…

19.12 Boost Asio 获取远程进程

远程进程遍历功能实现原理与远程目录传输完全一致&#xff0c;唯一的区别在于远程进程枚举中使用EnumProcess函数枚举当前系统下所有活动进程&#xff0c;枚举结束后函数返回一个PROCESSENTRY32类型的容器&#xff0c;其中的每一个成员都是一个进程信息&#xff0c;只需要对该容…

STM32笔记—EXTI外部中断

一、简介 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行&#xff1b; 中断优先级&…

AI:74-基于深度学习的宠物品种识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

【已解决】ChatGPT报错“Unable to load history Retry“等问题

解决ChatGPT历史加载错误&#xff1a;“Unable to load history Retry”问题指南 引言 在使用ChatGPT时&#xff0c;您可能遇到过一个常见的错误提示&#xff1a;“Unable to load history Retry”。这可能会阻止您查看以前的对话历史。本文将为您提供一个详细的教程&#xf…

c语言刷题第10周(16~20)

规律&#xff1a; 若多个次数最多按ASCII码顺序输出。 用for循环i取&#xff08;0~26&#xff09; 则输出满足条件的字符串中位置最靠前的那个。 用while循环遍历&#xff08;while&#xff08;a[i]!\0&#xff09;&#xff09; 从键盘输入任意只含有大小写字母的串s&…

node插件MongoDB(一)——MongoDB的下载和安装

文章目录 前言一、MongoDB的下载和安装1. 下载(1) 打开官网(2) 选择版本(3) 选择电脑系统和安装格式后点击下载(4) 将文件解压放到C:\Program Files文件目录下(5) 在c盘下创建文件夹(6) 启动服务端程序(7) 服务端程序启动成功效果(8) 在浏览器中输入127.0.0.1:27017查看效果&am…

拍摄视频的时候相机断电导致视频文件损坏,怎么修复

3-4 现在好多人都有自己的相机&#xff0c;但是专业用来录像的机器应该是不太可能都有的&#xff0c;相机的稳定性会比专业的机器差一些&#xff0c;如果用于比较重要的场景&#xff0c;比如婚庆、会议录像、家庭录像使用等&#xff0c;有较少的概率会出现一些奇怪的情况&…

界面组件DevExpress ASP.NET Core v23.1 - 进一步升级UI组件

DevExpress ASP.NET Core Controls使用强大的混合方法&#xff0c;结合现代企业Web开发工具所期望的所有功能。该套件通过ASP.NET Razor标记和服务器端ASP.NET Core Web API的生产力和简便性&#xff0c;提供客户端JavaScript的性能和灵活性。ThemeBuilder工具和集成的Material…

系列一、Shiro概述

一、概述 Shiro是一款主流的Java安全框架&#xff0c;不依赖任何容器&#xff0c;可以运行在JavaSE 和 JavaEE项目中&#xff0c;它的主要作用是对访问系统的用户进行身份认证、授权、会话管理、加密等操作。 一句话&#xff1a;Shiro是一个用来解决安全管理的系统框架&#x…