跨域:利用iframe实现跨域DOM互访的四种方式

注:跨域的知识点详见:跨域相关知识点

目录

实验验证环境配置:

1、利用document.domain降域

方法1:

方法2:

2、利用location.hash

3、利用window.name

4、利用postMessage(最推荐)

使用postmessage实现跨域访问

使用postmessage读取其他窗口的localstorage(普通款)

使用postmessage读取其他窗口的localstorage(加强版本):


实验验证环境配置:

我们一共需要配置五个虚拟主机,即需要使用五个域名

www.aaa.com、www.bbb.com、master.security.com、slave.security.com、www.security.com

(1)在本地的WWW目录下创建两个文件夹

cross_orgin和cross_orgin_sub

(2)域名分配:

cross_orgin:www.aaa.com

cross_orgin_sub:www.bbb.com

为了方便我们访问,这里需要在本地配置虚拟主机

(3)虚拟主机:

<VirtualHost *:80>
 DocumentRoot "F:/PHPstudy/phpstudy_pro/WWW/openlab/cross_orgin"
 ServerName  www.aaa.com
 FcgidInitialEnv PHPRC "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts"
 AddHandler fcgid-script .php
 FcgidWrapper "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts/php-cgi.exe" .php
 <Directory "F:/PHPstudy/phpstudy_pro/WWW/openlab/cross_orgin">
        Options FollowSymLinks ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
        DirectoryIndex index.php index.html
</Directory>
</VirtualHost>
​
<VirtualHost *:80>
 DocumentRoot "F:/PHPstudy/phpstudy_pro/WWW/openlab/cross_orgin_sub"
 ServerName www.bbb.com
 FcgidInitialEnv PHPRC "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts"
 AddHandler fcgid-script .php
 FcgidWrapper "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts/php-cgi.exe" .php
 <Directory "F:/PHPstudy/phpstudy_pro/WWW/openlab/cross_orgin_sub">
        Options FollowSymLinks ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
        DirectoryIndex index.php index.html
</Directory>
</VirtualHost>

 这里配置了两个虚拟主机:www.aaa.com 和 www.bbb.com分别对应的是我们所配置的

cross_orgin和cross_orgin_sub两个目录文件夹

(4)在vhost中配置ip与域名的对应关系

然后我们需要在本地环境的C:\Windows\System32\drivers\etc 目录下的vhost文件中增加对应关系

127.0.0.1 www.aaa.com
127.0.0.1 www.bbb.com

(5)我们可以在 cross_orgin和cross_orgin_sub 文件夹中任意创建页面文件,然后尝试使用域名进行访问

如果使用域名访问看到了编辑的页面内容,说明我们的环境已经搭建好了。

下面就详细的介绍一下ifame实现跨域DOM互访问的四种方式:

(6)

然后使用上面同样的方式完成master.security.com和slave.security.com和www.security,com这三个域名的搭建

这三个域名对应的是本地的cookie_orgin和cookie_orgin_sub、CSSinject文件夹

这里就只提供这三个域名的虚拟主机配置文件:

<VirtualHost *:80>
 DocumentRoot "F:/PHPstudy/phpstudy_pro/WWW/openlab/cookie_orgin"
 ServerName  master.security.com
 FcgidInitialEnv PHPRC "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts"
 AddHandler fcgid-script .php
 FcgidWrapper "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts/php-cgi.exe" .php
 <Directory "F:/PHPstudy/phpstudy_pro/WWW/openlab/cookie_orgin">
        Options FollowSymLinks ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
        DirectoryIndex index.php index.html
</Directory>
</VirtualHost>

<VirtualHost *:80>
 DocumentRoot "F:/PHPstudy/phpstudy_pro/WWW/openlab/cookie_orgin_sub"
 ServerName slave.security.com
 FcgidInitialEnv PHPRC "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts"
 AddHandler fcgid-script .php
 FcgidWrapper "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts/php-cgi.exe" .php
 <Directory "F:/PHPstudy/phpstudy_pro/WWW/openlab/cookie_orgin_sub">
        Options FollowSymLinks ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
        DirectoryIndex index.php index.html
</Directory>
</VirtualHost>

<VirtualHost *:80>
 DocumentRoot "F:/PHPstudy/phpstudy_pro/WWW/openlab/CSSinject"
 ServerName  www.security.com
 FcgidInitialEnv PHPRC "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts"
 AddHandler fcgid-script .php
 FcgidWrapper "F:/PHPstudy/phpstudy_pro/Extensions/php/php7.3.4nts/php-cgi.exe" .php
 <Directory "F:/PHPstudy/phpstudy_pro/WWW/openlab/CSSinject">
        Options FollowSymLinks ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
        DirectoryIndex index.php index.html
</Directory>

注:虚拟主机中的目录文件需要与自己本地的文件配置一致,不要直接使用我这个 

1、利用document.domain降域

方法1:

master.security.com 的index.html文件:

方法1:
<!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>Master</title>
</head>
​
<body>
    <h1>master</h1>
    <iframe id="iFrame" src="http://slave.security.com"></iframe>
    <!-- 这里将子页面嵌入到该页面中 -->
    <!-- 这里面填写子页面 -->
</body>
<script>
    document.domain = 'security.com'//domain进行降域不看子域名只看主域
    document.cookie = 'name=master'
</script>
</html>

这里将slave.security通过iframe嵌入到当前页面,并且这里在script标签中设置了document.domain,目的是让同样设置了这样的页面可以跨域互访,并还设置了一个document.cookie用于测试

    document.domain = 'security.com'//domain进行降域不看子域名只看主域
    document.cookie = 'name=master'

slave.security.com的index.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>slave</title>
</head>
​
<body>
    <h1>slave</h1>
</body>
<script>
    document.domain = 'security.com'
    alert(document.cookie);
</script>
</html>

这里就是我们用来测试的页面与前面一样设置了document.domain,并且尝试弹出第一个文件设置的cookie值 

将文件创建后以后,我们可以尝试使用访问一下slave.security.com测试:

可以看到这里确实弹出了cookie,但是并不是文件1中设置的cookie,所以这种方法并没有实现真正的跨域互访DOM

方法2:

master.security.com 的index.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>Master</title>
</head>
​
<body>
    <h1>master</h1>
    <iframe id="iFrame" src="http://slave.security.com"></iframe>
    <!-- 这里将子页面嵌入到该页面中 -->
    <!-- 这里面填写子页面 -->
</body>
<script>
    document.domain = 'security.com'//domain进行降域不看子域名只看主域名
    let ifr = document.getElementById('iFrame');
    ifr.onload = function () {//onload:等iFrame加载完成后再执行
        let win = ifr.contentWindow;//抓了子页面,赋值给win
        console.info(win);
        alert(win.data);//把这里抓到子页面的data弹窗出来
    }
</script>
​
</html>

这里和方法1一样设置了document.domain,但是不同的是,这里使用onload事件,必须要等到ifame加载完成后,在执行子页面的内容,然后这里还尝试将子页面的data尝试弹窗显示出来 

slave.security.com 的index.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>slave</title>
</head>
​
<body>
    <h1>slave</h1>
</body>
<script>
    document.domain = 'security.com'
    window.data = "这是data:111"
</script>
​
</html>

这里也是设置了与前面相同document.doamin,与方法1不同的是,这里没有了弹窗,反而定义了一全局变量 

然后我们就可以尝试访问matser.security.com测试:

可以看到成功的弹窗了,并且弹出阿里data的值正是子页面定义的值,所以这里成功利用domain降域实现了跨域DOM互访

总:方法1在这个实验在浏览器中已经无法实现了,方法2可以正常实现

2、利用location.hash

(1)aaa.com(index.html文件)

   var ifr = document.createElement('iframe')
    ifr.src = 'http://www.bbb.com#data';
    ifr.style.display = 'none';
    document.body.appendChild(ifr);
    function checkHash() {
        try {
            let data = location.hash ? location.hash.substring(1) : ' ';
            console.log('获取到的数据为:', data);
        } catch (e) {
        }
    }
    checkHash();
    window.addEventListener('hashchange', function (e) {
        console.log('获取到的数据为:', location.hash.substring(1));
    });

这里首先将www.bbb.com子页面引入到本页面,并且增加一个锚点data,然后checkHash函数中进行了异常处理,try中对data进行判断,判断这是不是一个location.hash,如果是则取出#后的数据,不是就置为空,然后打印出data的数据 

后面再进行了对hashchange的监听

(2)bbb.com(index.html文件)

   switch (location.hash) { // 判断location1哈希
        case "#data":
            callback(); //调用函数
            break;
    }
    function callback() {
        const data = "some number:11111"
        try {
            parent.location.hash = data; //把自定义的值赋值给父页面的哈希值(即,改变了父页面的哈希)
        } catch (e) {
            //利用一个中间代理页面ifame(cs3.html)
            //要求:需要和第一个页面是同源
            var ifrproxy = document.createElement('iframe');
            ifrproxy.style.display = 'none';
            ifrproxy.src = "http://www.aaa.com/c.html#" + data;
            document.body.appendChild(ifrproxy);
        }
    }
    //获取父页面中的body标签中的内容

 这里对location.hash进行判断,如果是#data则调用回调函数,回调函数中对data进行了赋值,并且将该值赋值给了父级的location.hash,然后后面利用了c.html作为中间代理页面,将data值传给父级

(3)中间代理c.html文件

parent.parent.location.hash = self.location.hash.substring(1)

这里就是将自己的location.hash中后面#中的值,赋值给父级的父级也就是bbb.com的父级aaa.com 

(4)测试

我们尝试访问一下www.aaa.com

可以看到我们成功的使用c.html作为中间代理,使用www.aaa.com访问到了www.bbb.com中的值,实现了跨域DOM互访的目的

缺点:

  • 数据直接暴露在URL中

  • 数据容量和类型都有限

总:这种方法已经被淘汰了

3、利用window.name

windows.name(一般在js代码中出现)的值不是一个普通的全局变量,而是当前窗口的名字,要注意的是每个iframe都有包裹它的window,而这个window是top window的子窗口,而它自然也有window.name的属性。

window.name的属性的神奇之处就在于name的值在不同的页面(甚至不同的域名)加载后依然存在(如果没有修改则值不会变化),并且可以支持非常长的name值(2MB)

举一个简单的例子:你在某个页面的控制台输入:

window.name="hello world"
window.location="http://www.baidu.com"

页面跳转到了百度的页面,但是window.name却被保留下来,还是hello world

那么我们现在可以利用window.name这一性质来尝试进行跨域访问

(1)security.com(window_name.html)

    var ifr = document.createElement('iframe');
    ifr.style.display = 'none';
    ifr.src = "http://www.aaa.com";
    document.body.appendChild(ifr);
    ifr.onload = function () {
        ifr.onload = function () {
            let data = ifr.contentWindow.name;
            console.info(data);
        }
        ifr.src = "http://www.security.com/c.html"
    }

这里的windo_name.html文件中使用iframe将www.aaa.com作为子页面引入到当前页面,然后使用加载时间,来获取当前页面的,window.name值,并且打印出来,后面还指定了监听源为:www.security.com/c.html 

(2)www.aaa.com(index.html)

    window.name = "hello aaaa";

这里只需要定义一个window.name即可 

(7)c.html

(8)测试

可以看到这里成功的访问到了www.aaa.com中定义的window.name的值,并且,当前的Window.name的值为' '

总:当www.security.com/window_name.html在请求远端服务器www.aaa.com的数据时,我们可以在该页面下新建一个iframe,该iframe的src属性指向服务器地址(利用iframe标签的跨域能力),服务器文件aaa.com设置好了window.name值

但是由于window_name页面与aaa.com页面的iframe的src不同源的话,则无法操作iframe里面的任何东西,所以就取不到iframe的name值,所以我们只需要在aaa.com加载完成后重新换一个src指向同一个源的html文件,或者设置about:blank都行,这时候我们只要在window_name相同的目录下创建一个c.html空白文件即可,如果不重新指定src的话直接获取window.name就会报错

注:以上的方式均属于hack

4、利用postMessage(最推荐)

使用postmessage实现跨域访问

(1)security.com

  window.onload = function () {
        let targetOrigin = 'http://www.aaa.com'; //想要去的地址,即给它发送消息
        window.frames[0].postMessage('向aaa.com发送消息', targetOrigin);
    }
    window.addEventListener('message', function (e) {
        console.log('security.com接收到的消息', e.data);
    });

这里使用了一个事件监听着一个函数,函数中的tarOrigin指向www.aaa.com,这里表示为发送消息的接收地址,后面使用Postmessage向aaa.com发送消息,后面监听了消息这个事件 

(2)aaa.com

方案1:  
window.addEventListener('message', function (e) {
        if (e.source != window.parent)
            return;
        let data = e.data;
        console.log("aaa.com接收到的消息", data);
        // window.frames[0].postMessage("向aaa.com发消息", targetOrgin);
        parent.postMessage('aaa.com发送security', e.origin);
    }, false);

 这里定义了一个监听事件,监听消息,如果消息的源不是父级传递来的,则直接返回,否则将父级消息赋值给data,并且打印出来,然后后面也使用了postmessage向www.security发送消息

方案2:
    window.addEventListener('message', receiveMessage);
    function receiveMessage(event) {
        if (event.origin !== 'http://www.security.com') return;
        //事件的源地址
        if (event.data === 'Hello World') {
        //事件的内容
            event.source.postMessage('Hello', event.origin);
            
} else {
            console.log(event.data);
        }
    }

这里的实现是使用了event的几个属性来实现的 

(3)测试

方案1:

可以看到,www.aaa.com和www.security.com都互相收到了跨域发送的消息

方案2:

这里可以看到www.security也成功的接收到了ww.aaa发送的消息

使用postmessage读取其他窗口的localstorage(普通款)

(1)security/index.html

 window.onload = function () {
        let targetOrigin = 'http://www.aaa.com'; //想要去的地址,即给它发送消息
        var obj = { name: '杨攀帅', age: 20, 'wigth': 100 }
        window.frames[0].postMessage(
            JSON.stringify({ key: 'storage', method: 'set', data: obj }), targetOrigin
        );
    }
    window.addEventListener('message', function (e) {
        console.log('security.com接收到的消息', e.data);
    });

(2)aaa.com/index.html

    window.addEventListener('message', receiveMessage);
    function receiveMessage(event) {
        if (event.origin !== 'http://www.security.com') return; //信息来源判断
        var payload = JSON.parse(event.data);
        localStorage.setItem(payload.key, JSON.stringify(payload.data))
    }

(3)测试

可以看到,aaa.com页面成功使用postmessage读取到了security.com页面中的数据,并且存储到了本地

使用postmessage读取其他窗口的localstorage(加强版本):

(1)security/index.html

 window.onload = function () {
        let targetOrigin = 'http://www.aaa.com'; //想要去的地址,即给它发送消息
        var obj = { name: 'yps', age: 20, 'wigth': 100 }
        //加强版
        window.frames[0].postMessage(
            JSON.stringify({ key: 'storage', method: 'set', data: obj }),
            'http://www.aaa.com'
        );
        window.frames[0].postMessage(
            JSON.stringify({ key: 'storage', method: 'get' }),
            '*'
        );
        window.frames[0].postMessage(
            JSON.stringify({ key: 'storage', method: 'remove' }),
            '*'
        );
    }
    window.onmessage = function (e) {
        if (e.origin != 'http://www.aaa.com') return;
        console.log(JSON.parse(e.data).name
        );
    };

这里的大致思路和上面一样,那为什么说它是一个加强版本呢,因为,这里我们可以自己选择时set、还是get、还是remove Messageage发送的消息 

需要注意的是,要想让数据存储下来,需要将remove注释掉,否则将无法正常的读取到数据

(2)aaa.com/index.html

window.addEventListener('message', receiveMessage);
    function receiveMessage(event) {
        if (event.origin !== "http://www.security.com") return;
        var payload = JSON.parse(event.data)
        switch (payload.method) {
            case 'set':
                localStorage.setItem(payload.key, JSON.stringify(payload.data))
                break;
            case 'get':
                var parent = window.parent;
                var data = localStorage.getItem(payload.key)
                parent.postMessage(data, 'http://www.security.com/')
                break;
             case 'remove':
                 localStorage.removeItem(payload.key)
                 break;
            default:
                break;
        }
    }

这里也是增加了set、get、remove的选项看,并且完成了对应操作的实现 

(3)测试

这里也是一样的,可以看到,aaa.com页面成功使用postmessage读取到了security.com页面中的数据,并且存储到了本地

注:如果在将数据存入数据中没有转换/存储时转换为JSON格式时会报错

到这里使用iframe实现跨域DOM互访的几种方法已经介绍完毕了,更多跨域的内容请看下篇分享

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

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

相关文章

视频剪辑助手:轻松实现视频随机分割并提取音频保存

随着社交媒体和视频平台的日益普及&#xff0c;视频制作和分享已成为人们日常生活的一部分。无论是分享个人生活&#xff0c;还是展示才艺&#xff0c;或是推广产品&#xff0c;视频都是一个非常有效的工具。但是&#xff0c;视频制作往往涉及到大量的视频剪辑工作&#xff0c;…

卡码网语言基础课 | 11. 句子缩写

目录 一、 字符串大小的比较 二、 ASCII码值 三、 基本框架代码 四、 解题思路 4.1 首字母问题 4.2 判定小写字母 4.3 小写字母转换为大写字母 五、空格判断 六、 代码模块化 6.1 满足的条件 6.2 代码完善 七、 题目解答 7.1 原始代码 7.2 改进代码 八、 拓展与…

Redis五种数据类型及命令操作(一)

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 知足知不足 有为有不为 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349; 本篇记录Redis五种数据类型及命令操作&#xff0c;如…

[BJDCTF2020]Easy MD5 1

题目环境&#xff1a; 尝试了SQL注入、命令执行等都不行 点击提交并burp进行抓包Repeater进行重放这里看到了内置的SQL语句select * from admin where passwordmd5($pass,true) 发现传进去的值会进行md5加密 这里看了大佬们的解释 ffifdyop绕过&#xff0c;绕过原理是&#xff…

计算机网络期末复习-Part3

1、rdt1.0&#xff0c;rdt2.0&#xff0c;rdt3.0的底层信道模型 RDT 1.0: 完全可靠的底层信道&#xff0c;没有比特差错&#xff0c;也没有分组丢失。 RDT 2.0: 具有比特差错的底层信道&#xff0c;有比特差错&#xff0c;但没有分组丢失。 RDT 3.0: 具有差错和丢包的底层信道…

聊聊性能测试的左移右移

前面的文章中&#xff0c;分享过我对于测试左移右移的一些思考和实践方法。有同学在后台留言问我&#xff1a;常规的性能测试一般都是在测试阶段集成测试时候才开始介入&#xff0c;很容易测试时间不够&#xff0c;可不可以借鉴测试左移右移的思路&#xff0c;更早的介入和发现…

实战Leetcode(三)

Practice makes perfect&#xff01; 实战一&#xff1a; 带环问题其实我们小学时就接触过&#xff0c;就比如在操场上比赛跑步的追击问题&#xff0c;这里也是一样&#xff0c;如果我们定义两个指针&#xff0c;一个快指针&#xff0c;一个慢指针&#xff0c;快指针走的快&…

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:

错误描述如下所示&#xff1a; 我们将错误拉到最下面如下所示为导致异常的原因&#xff1a; Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type com.example.reviewmybatisplus.Service.UserService available: expec…

基于Mahony互补滤波的IMU数据优化_学习笔记整理

这周自己被安排进行优化软件 IMU 姿态解算项目&#xff0c;之前自己只简单了解四元数&#xff0c;对IMU数据处理从未接触&#xff0c;通过这一周的学习感觉收获颇丰&#xff0c;在今天光棍节之际&#xff0c;&#xff0c;&#xff0c;用大半天的时间对这一周的收获进行整理&…

SwiftUI 如何保证 Text 中字符数量相等的字符串显示宽度一定相同?

0. 问题现象 在 SwiftUI 中我们往往需要将内容相似的字符串展列出来给用户比较,这些字符串内容各有不同但字符数量始终是相等的,我们希望它们的显示宽度始终保持一致: 如上图所示:即使是等宽字符组成的字符串在字符数量相等时它们的显示宽度仍然可能不一致。但演示中最底部…

迷雾系统-人物驱散迷雾

使用linerRender,将人物移动数据动态添加进去&#xff0c;同样是特殊层级让FogCamera渲染 EndCapVertices的数量越多&#xff0c;矩形就变为一个椭圆形的形状&#xff0c;更适合圆形视野探索 当拐点的两个点距离太近&#xff0c;LineRender会发生扭曲&#xff0c;解决方案是在…

14 # 手写 debounce 防抖方法

什么是防抖 防抖: n 秒后再去执行该事件&#xff0c;若在 n 秒内被重复触发&#xff0c;则重新计时&#xff0c;这个效果跟英雄联盟里的回城技能差不多。 本质上是优化高频率执行代码的一种手段&#xff0c;目的就是降低回调执行频率、节省计算资源。 应用场景&#xff1a; …

灵活用工仿boss直聘招聘系统劳务系统源码

灵活用工仿boss直聘招聘系统劳务系统 开发语言&#xff1a; 后台&#xff1a;phpmysql&#xff0c;fastadmin框架 前端&#xff1a;vue&#xff0c;Uniapp 功能介绍&#xff1a; 1.登录 账号密码登录&#xff0c;微信手机号授权登录 2.首页&#xff1a;定位功能&#xf…

2023最新软件测试面试300问

一、Linux系统应用和环境配置 1、Linux系统的操作命令给我说10个&#xff0c;一般用什么工具远程连接Linux服务器&#xff1f; 2、Linux中的日志存储在哪里&#xff1f;怎么查看日志内容&#xff1f; 3、Linux中top和ps命令的区别&#xff1f; 4、Linux命令运行的结果如何写…

《013.Springboot+vue之旅游信息推荐系统》【前后端分离有开发文档】

《013.Springbootvue之旅游信息推荐系统》【前后端分离&有开发文档】 项目简介 [1]本系统涉及到的技术主要如下&#xff1a; 推荐环境配置&#xff1a;idea jdk1.8 maven MySQL 前后端分离; 后台&#xff1a;SpringBootMybatisMySQL; 前台&#xff1a;Vue; [2]功能模块展…

暖手宝+充电宝设计方案 可实现快速升温和充电 低成本充电电流可选

充电暖手宝因为它的便携性&#xff0c;既能供暖又能当充电宝使用而备受人们喜爱。是冬天暖手供暖的必备神器。 目前&#xff0c;市场常见的暖手宝大致有三个类型&#xff0c;分别是加热水的热水袋、通过化学反应放热的铁粉袋子和锂电供电的智能暖手宝。与常见的暖手宝不同&…

如何将BMP图片批量转为PNG透明图片,并去掉BMP黑色背景

将BMP图片批量转为PNG透明图片&#xff0c;并去掉BMP黑色背景&#xff0c;这里推荐一款软件bmp2png&#xff0c;关键是免费的。截图如下&#xff1a; 这个小软件不仅可以将bmp图片批量转为png图片&#xff0c;而且还增加了压缩功能&#xff0c;导出png图片时压缩导出图片&#…

order by的注入与Insert ,update和delete注入

order by的注入 Insert &#xff0c;update和delete注入

告别龟速,从GitHub快速下载项目的技巧分享,简单又高效!

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…

Linux中的粘滞位

目录 粘滞位1、作用2、为什么添加粘滞位3、演示粘滞位的使用方法和效果 粘滞位 1、作用 为了多人协作写进行文件创作时&#xff0c;other用户没有办法将文件删除&#xff0c;只有超级管理员、该目录的所有者、该文件的所有者他们可以删除。 2、为什么添加粘滞位 你想在进行…