你是否每次面试前都要临时抱佛脚,重温一遍跨域的知识?

前言

思考

你是否每次面试前都要临时抱佛脚,重温一遍跨域的知识?

你看了那么多的跨域文章,为什么还要花时间反复的学习这个知识点?

你真的是记性不好,学完就忘了吗?

我的观点

记性并非是阻碍我们学习的主要因素,真正的原因可能在于你的学习方法有待改进。

在学习过程中,我们往往容易满足于表面的“看懂”,认为只要把文字或公式读懂了,就是真正掌握了这个知识点。但实际上,这种“看懂”只是一种浅显的认识,它并没有深入到知识点的核心和本质。而真正的理解,则要求我们能够将新知识与已有的知识框架进行有机的整合,形成一个完整、连贯的认知结构。这就像是建造一栋房子,单纯地搬运砖块并不能解决问题,关键是要知道如何将这些砖块按照正确的顺序和方式砌建成一座稳固的房子。

验证我的观点

今天,我们就来打破这个僵局,从基础到深入,彻底揭开跨域的神秘面纱。

正文

换个思维理解什么是跨域

想象一下你住在一个小区里,你可以自由地在小区内走动,访问任何一个你想去的地方。但是,如果你想去对面小区找朋友借个充电器,通常会有小区的门禁挡住去路。这个小区的门禁就为了阻止了你直接进入另一个区域,它有效的保障了自己小区内的人员安全,为了防止小偷、抢劫犯、推销人员等等。

但是它的缺点也不言而喻,限制了你走亲访友的自由。

现在,把“小区”想象成“网站”,每个网站都有自己的规则和限制。当你试图从一个网站(我们称之为“网站A”)获取信息或与之交互时,网站A的规则不允许你这样做,除非你通过它特定的“通行证”来证明你的身份和意图。这种情况就叫做“跨域”,他的规则就是“浏览器的同源策略”。

同样,跨域也限制了Web应用的灵活性,所以我们需要解决跨域。

从“道”的层面理解跨域的解决方法

我们再来讲小区,难道区区一个门禁就能阻止外人进入了么?

当然不是,那手段太多了,这里列举几个

1 JSONP(JSON with Padding)

这是一个古老的方法。

JSONP可以理解帮忙跑腿,你小区的门是上个年代的,有门缝(<script>标签),你认识那个小区的门卫大爷,你让大爷帮你去拿充电器,然后再回来通过你小区的门缝塞给你。整个过程都在你的监督之下完成的,确保了安全性。

所以说<script>标签实际上是绕过了浏览器的同源策略限制

理解完了看实例

(1)前端部分

<head>
    <script type="text/javascript">
        // 你发现了门缝,大爷从这里给你塞充电器
        function handleResponse(data) {
            console.log(data.message); // 输出: 给你充电器
        }

        $.ajax({
            url: 'https://friends.com/api/data',
            type: 'GET',
            dataType: 'jsonp',
            jsonpCallback: 'handleResponse',
            success: function(response) {
                // 这里的success不会被执行,因为我们使用了JSONP
                console.log(response);
            }
        });
    </script>
</head>

(2)后端部分

// 大爷get到你的需求了,你要拿充电器“/api/data”
app.get('/api/data', (req, res) => {
    const data = { message: '给你充电器' }; // 取到充电器了
    res.jsonp(data); // 通过门缝塞给你
});

2. Document.domain(文档域设置)

你和你朋友决定一起干点大事,你们决定一起调整门禁系统,你们把自己小区的门禁都破解了(将双方的“document.domain”属性都设置为相同主域名""),这样你们就都能进入对方的区域,畅通无阻了。

(PS:这里只是举例做学术研究,大家不要模仿)

理解完了看实例:

(1)朋友小区html:源域名"朋友小区.房产商.com"

<head>
    <script type="text/javascript">
        // 当文档加载完成时执行
        window.onload = function() {
            // 破解门禁
            document.domain = "房产商.com";

            // 现在可以访问"你家.房产商.com"了
            var iframe = document.createElement("iframe");
            iframe.src = "http://朋友小区.房产商.com/xxx.html";
            document.body.appendChild(iframe);

            // 添加一个事件监听器,当iframe中的页面加载完毕时触发
            iframe.onload = function() {
                // 现在iframe中的页面和当前页面属于相同的主域
                alert("会面成功!");
            };
        };
    </script>
</head>

(2)你小区.html:源域名"你小区.房产商.com"

<head>
    <script type="text/javascript">
        // 当文档加载完成时执行
        window.onload = function() {
            // 破解门禁
            document.domain = "房产商.com";

            // 现在可以访问朋友家了
            // 例如,可以在这里编写代码来与"朋友小区.房产商.com"上的脚本进行交互
        };
    </script>
</head>

3. window.postMessage()

你们俩在各自小区门外都做了个暗格,放了个带密码的保险柜(window.postMessage),通过它,你们可以方向的互相借东西,只有你俩才知道密码并打开。

(PS:这里只是举例做学术研究,大家不要模仿)

理解完了看实例:

(1)朋友小区.html

<head>
    <script type="text/javascript">
        // 朋友给你的保险柜放东西
        function sendMessageToReceiver() {
            // 这里假设我们已经有了目标窗口的引用,存储在变量receiverWindow中
            var receiverWindow = getReceivingWindow();
            // 创建要发送的消息对象
            var message = {
                text: '充电器给你。',
                origin: 'http://朋友小区.房产商.com'
            };
            // 发送消息到目标窗口
            receiverWindow.postMessage(message, 'http://你小区.房产商.com');
        }

        // 朋友查收你给朋友放的东西
        function getReceivingWindow() {
            // 这里返回的是目标窗口的引用,具体的获取方式取决于实际的应用场景
        }

        // 假设这个函数是在某个事件(如按钮点击)中被调用
        function handleButtonClick() {
            sendMessageToReceiver();
        }

        // 给按钮添加点击事件监听器
        document.getElementById('sendButton').addEventListener('click', handleButtonClick);
    </script>
</head>
<body>
    <button id="sendButton">发送消息</button>
</body>

(2)你小区.html

<head>
    <script type="text/javascript">
        // 查看自己小区保险柜
        function receiveMessageFromSender(event) {
            // 在这里处理来自朋友.html的消息
            console.log("收到物品:", event.data.text);
            // 如果需要,可以向发送者发送确认消息
            event.source.postMessage({ received: true }, event.origin);
        }

        // 添加事件监听器来接收来自其他窗口的消息
        window.addEventListener("message", receiveMessageFromSender, false);

        // 初始化代码,例如设置页面的标题等
        window.onload = function() {
            document.title = "保险柜准备好了";
        };
    </script>
</head>

4. CORS(跨源资源共享)

你们俩的小区是同一个开发商的,你们俩向开发商申请了一张高权限的门禁一卡通(CORS Header),里面登记了你和你朋友的信息(在请求头添加一个身份来源标识),下次再串门刷门禁,系统就会知道你们已经被授权可以自由出入两个小区了。

开发商可以理解为服务器,在服务器设置了支持访问的源,这样服务器端可以根据标识判断是否可以访问并给予响应

理解完了看实例:

(1)服务端

@Configuration
public class CorsGlobalConfigurer implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://friends.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
    }
}

(2)用户端

axios.get('http://friends.com/api/data')
     .then(function (response) {
          console.log('朋友回复:', response.data); // 充电器来了
     })
     .catch(function (error) {
          console.log('error:', error);
     });

5. Proxy Serve(代理服务器)

社会的发展衍生出了一个新职业,专业跑腿机构,例如外卖骑手,假设外卖骑手都是经过实名认证和征信备案的。他是连接你和你朋友的桥梁(代理),他不仅有能力进入两个小区,还能确保充电器不会丢失(信息的准确传递)。而你,作为雇佣跑腿的人,只需要关注充电器本身(信息本身),而无需担心如何越过那道门禁。

理解完了看实例:

webpack.config.js

module.exports = {
  // ... 其他配置 ...
  devServer: {
    proxy: {
      '/api': 'http://外卖骑手:3000' // 将去朋友家带充电器'/api'的请求让外卖骑手代理
    }
  }
  // ... 其他配置 ...
};

总结

理解了跨域的本质,你就能明白,解决跨域并非只是背一些理论概念,学习几种技术手段,更重要的是理解背后的安全考量和设计思路。

无论是在面试中还是在实际开发中,能够深入剖析跨域的原理,展示出对Web安全和浏览器机制的深入理解,根据具体需求和浏览器的兼容性情况选择合适的跨域解决方案。

同时,为了保证网络通信的安全性,开发者在使用这些技术时也应该注意防范潜在的安全风险,如XSS攻击和CSRF攻击等。

现在,你是否对跨域有了更清晰的认识呢?不再只是机械地记忆解决方案,而是能够从更高的角度去理解和应用,这才是真正节省时间,提升技能的方式。希望这篇文章能帮你拨云见日,让跨域不再是你的困扰。

心得

初次尝试,尚显稚嫩。期待在未来的日子里,与大家共同成长,共同进步。

希望大家能喜欢我的作品,并给予我更多的支持和鼓励。谢谢大家!

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

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

相关文章

直播话术核心逻辑,学了轻松提高销量!沈阳直播运营培训

直播话术到底该怎么说&#xff1f; 产品话术说得好&#xff0c;直播间一次就能卖出去上万件产品&#xff1b;产品话术说不好&#xff0c;直播间半个月也卖不出去10件产品。 我们上次就有跟大家说过产品话术的具体流程&#xff0c;但发现还有更多朋友居然还是不能够很好地完成一…

2024/5/6 QTday1

自由发挥应用场景&#xff0c;实现登录界面。 要求&#xff1a;尽量每行代码都有注释。 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//窗口相关设置this->resize(350,470);this->setFixedSize(350,470);//窗口标题this-&g…

一个简单的仓库出入库管理软件的流程是什么样的?有哪些功能?

身为仓库文员&#xff0c;我深知仓库管理对于公司运营的重要性。仓库是公司物资的中转站&#xff0c;其管理的好坏直接关系到公司的运营效率和成本控制。然而&#xff0c;传统的仓库管理方式往往存在着效率低下、易出错等问题&#xff0c;为了解决这些问题&#xff0c;我们需要…

uboot图形界面配置

文章目录 一、环境安装二、配置默认项2.图形界面 三、图形配置项的来源1.mainmenu主界面 一、环境安装 &#x1f4a6;uboot 或 Linux 内核可以通过输入“make menuconfig”来打开图形化配置界面&#xff0c;menuconfig是一套图形化的配置工具&#xff0c;需要 ncurses 库支持。…

2024年电工杯数学建模竞赛A题B题思路代码分享

您的点赞收藏是我继续更新的最大动力&#xff01; 欲获取更多电工杯学习资料&#xff0c;可点击如下卡片链接 点击链接加入群聊【2024电工杯】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&k_PrjarulWZU8JsAOA9gnj_oHKIjFe195&authKeySbv2XM853pynlnXiv6M58…

解决github的remote rejected|git存储库的推送保护

前言 git存储库的推送保护。当你试图推送代码到GitHub仓库时&#xff0c;由于存在与主分支&#xff08;master&#xff09;相关的仓库规则违规行为&#xff0c;推送会被拒绝了。这种保护机制帮助确保只有经过授权和符合规定的代码才能被合并到主分支&#xff0c;从而保护了主分…

网络聊天室:通过Servlet和JSP,结合session和application实现(文末附源码)

目录 一.成品效果 二.代码部分 chat.jsp ChatServlet 一.成品效果 在启动成功后&#xff0c;我们就可以在任意俩个浏览器页面中相互发消息&#xff0c;如图所示左边屏幕使用的是Edge浏览器&#xff0c;右图使用的是火狐浏览器。当然笔者这里只是简单实现最基本的一些功能&…

【LeetCode刷题记录】105. 从前序与中序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树

105 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,1…

Linux--IIC驱动编程实验

对于 I2C 主机驱动&#xff0c;一旦编写完成就不需要再做修改&#xff0c;其他的 I2C 设备直接调用主机驱动提供的 API 函数完成读写操作即可。这个正好符合 Linux 的驱动分离与分层的思想&#xff0c;因此 Linux内核也将 I2C 驱动分为两部分&#xff1a; ①、 I2C 总…

盘一盘接口测试的那些痛点,你现在会解决了吗

前言 说到接口测试&#xff0c;想必大家一定不会陌生。接口测试就是测试系统组件间&#xff0c;接口对接是否顺畅的一种测试。包括测试数据能否交换、能否传递、能否正常控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系&#xff0c;等等。 由于接口测试主要是检测系统…

5月3日江苏某厂冷却塔清洗工作汇报-智渍洁

5月3日 施工人员&#xff1a;张能超&#xff0c;张伟&#xff0c;刘平&#xff0c;曾巧 施工事项&#xff1a;空冷器脱脂 今日工作进度&#xff0c;清洗6台遇到的问题&#xff0c;就是那个喷雾器不经用&#xff0c;一会儿又坏了 重庆智渍洁环保科技有限公司专注于工业清洗&…

使用ThemeRoller快速实现前端页面风格美化

使用ThemeRoller快速实现前端页面风格美化 文章目录 使用ThemeRoller快速实现前端页面风格美化一、ThemeRoller二、使用方法1.基本操作面板介绍2.直接用现成的配色风格——Gallery画廊3.自定义风格——Roll Your Own4.下载风格包并应用到页面 一、ThemeRoller ThemeRoller是jQ…

欢乐钓鱼大师脚本,游戏托管一键操作!

欢迎来到《钓鱼大师乐趣无穷》&#xff01;这里是一片充满了乐趣和挑战的钓鱼天地。不论你是刚刚入门的小白&#xff0c;还是已经成为老手的大神&#xff0c;本攻略将为你揭示如何在游戏中获得成功&#xff0c;并针对稀有鱼类的钓鱼技巧进行详细介绍。 一、初探钓鱼的乐趣 在《…

GEE错误——image.reduceRegion is not a function

简介 image.reduceRegion is not a function 这里的主要问题是我们进行地统计分析的时候&#xff0c;我们的作用对象必须是单景影像&#xff0c;而不是影像集合 错误"image.reduceRegion is not a function" 表示你正在尝试使用reduceRegion()函数来处理图像数据&…

MySQL数据库—多表设计(有这一篇够!)

▐ 数据库设计范式 • 第一范式&#xff1a;确保每列保持原子性 ( 列不可再分解 ) 例如联系方式包括&#xff1a;电话/邮箱/微信... 那么我们设计表时就需要将它具体化 • 第二范式&#xff1a;要有主键&#xff0c;通过主键可以精确的定位到某行数据. 其他字段都依赖于主…

JAVA----Thread(2

Thread 提供的属性和方法 目录 Thread 提供的属性和方法一.构造方法1.Thread() :2.Thread(Runnable target) :3.Thread(String name) :main 线程 4.Thread(Runnable target, String name) : 二.属性1.ID (getId)2.名称(getName)3.状态(getState)4.优先级 (getPriority)5.是否后…

如何用中医揿针治疗肩周炎?

点击文末领取揿针的视频教程跟直播讲解 首先我们先来了解什么是肩周炎 【中医辨证】 肩周炎中医称之为漏肩风、锁肩风、肩凝症等&#xff0c;将肩周炎的一系列症状归纳为痹证的范畴&#xff0c;故又有肩痹、肩胛周痹等病名。 在中医古典医籍《素问痹论》中有骨痹、筋痹、脉…

LangChain Agent最全教程学习

LangChain Agent的终极指南&#xff0c;本教程是您使用 Python 创建第一个agent的重要指南&#xff0c;请立即开始你的 LLM 开发之旅。 一、什么是LangChain Agent&#xff08;代理&#xff09; LangChain中代理背后的想法是利用语言模型以及要执行的一系列操作。代理正在使用…

C++常用库函数——strcmp、strchr

1、strcmp&#xff1a;比较两个字符串的值是否相等 例如 char a1[6] "AbDeG",*s1 a1;char a2[6] "AbdEg",* s2 a2;s1 2;s2 2;printf("%d \n", strcmp(s1, s2));return(0); s1指向a1&#xff0c;s2指向a2&#xff0c;strcmp表示比较s1和s…

Stable Diffusion学习记录

文章目录 前言电脑配置推荐环境搭建下载地址安装步骤步骤一&#xff0c;打开下载的秋叶整合包&#xff0c;路径秋叶整合包/sd-wenui-aki步骤二&#xff0c;打开下载好的sd-webui-aki-v4.8.7解压包 Stable Diffusion软件配置&#xff0c;插件安装&#xff0c;模型下载Stable Dif…
最新文章