客户端“自废武功”背后的深层秘密——CORS跨域是怎么回事?

嘿,对于刚入门的开发新手,你是不是曾经遇到过这样的情况:你正在愉快地开发一个 Web 应用,代码写得热火朝天,前后端配合得天衣无缝,直到某天你开始用 fetch 或者 axios 发送跨域请求,突然间,客户端跳出了一个巨大的“CORS 错误”,让你愣在了屏幕前。这时你可能会心里想:“客户端,难道你就是这么对待我努力开发的成果吗?!”别急,今天我们就来揭开客户端拒绝跨域请求的“幕后黑手”,搞清楚它为什么要这么做,是为了“自废武功”,还是有更深的原因呢?


1. 客户端的“自废武功”?

你一定遇到过这样的情景:你在写一个 Web 应用,开发得有声有色,一切都很完美,直到你开始发送跨域请求,突然间,客户端给你抛出了一个“CORS 错误”。你可能会想:“等一下!明明我得到了响应,为什么客户端还是拒绝了我的请求?!”这不禁让人想到了武侠片中的情节——“明明可以接招,却偏偏自己放弃武功”,就这么把请求给拒绝了。

其实,冷静一下!客户端可没有“自废武功”。它这样做是因为有一项非常重要的安全机制:同源策略(Same-Origin Policy)。这项策略的存在是为了防止跨站脚本攻击(XSS)和跨站请求伪造(CSRF),保护我们的数据不被恶意网站窃取。客户端在收到响应后,严格按照规则判断,如果跨域请求不合法,它就会果断地拒绝。


2. 为什么客户端需要同源策略?

想象一下,你正在使用一个银行网站,突然一个恶意网站发起了跨域请求,试图窃取你的账户余额,这可就麻烦了!为了避免这种情况,客户端必须执行同源策略,只有来自相同源(协议、域名和端口都相同)的请求才能访问该网站的资源。如果你从 http://evil.com 发起对 http://bank.com 的请求,客户端会毫不犹豫地拒绝你。这就像银行的保镖严格审查每个进门的顾客,不让任何不明身份的人进入。


3. CORS:让跨域变得更友好

当然,客户端也不是一味的“铁板一块”,它也知道有时候我们确实需要跨域请求,特别是当你的前端项目和后端服务部署在不同的域名下。那怎么办?这时候就需要CORS(跨源资源共享)出场了!CORS 是一种服务器授权机制,通过在 HTTP 响应头中设置,告诉客户端哪些跨域请求是被允许的。

就好比你有一张VIP通行证,前端请求符合 CORS 规则时,客户端就会让你顺利通过。否则,客户端就会拦下不符合规定的请求。

例如:

Access-Control-Allow-Origin: http://frontend.com

这行代码告诉客户端,只有来自 http://frontend.com 的请求被允许跨域访问资源,其他来源的请求都要敬而远之。


4. 客户端和服务器的默契配合

那么,究竟是谁在主导跨域请求呢?客户端自己决定跨域吗?答案是:不完全是!其实,真正的“主导者”是服务器。客户端只是根据服务器的指令行动,只有当服务器设置了正确的 CORS 响应头时,客户端才会允许跨域请求。如果服务器没设置这些头,客户端就会拒绝请求。

想象一下,客户端就像派对的门卫,而服务器是派对的主人。只有派对主人给了特定的通行证,客户端才会放行,允许客人进入。


5. 默认的跨域设置是啥?

很多人可能会问:“那客户端默认支持跨域吗?” 答案是:不支持!客户端默认执行同源策略,它不会主动发起跨域请求,除非遇到一些不涉及 JavaScript 的特殊情况(如 <img><script> 标签加载外部资源)。如果没有明确的授权,客户端会坚守自己的边界,不轻易放行跨域请求。


6. 案例:Tomcat 的 Filter 配置解决跨域问题

让我们再来看看如何通过实际配置来解决跨域问题。在使用 Tomcat 作为 Web 服务器时,跨域问题通常是通过配置一个 filter 来解决的。这个 filter 就是通过在请求到达服务器时,在 HTTP 响应头中加入必要的 CORS 配置,告诉浏览器哪些跨域请求是合法的。

例如,你可以在 web.xml 配置文件中添加如下的 CORS 配置:

<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter> <filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

通过这个配置,Tomcat 就会在每个响应头中自动加入必要的 CORS 响应头(比如 Access-Control-Allow-Origin),允许来自不同域的请求合法访问。这样,服务器就能按照 CORS 规范,正确处理跨域请求,客户端就不会再拒绝这些请求。

总结:

原来,客户端并不是“自废武功”,它只是在严格执行 同源策略,以确保用户的安全,防止跨站脚本攻击(XSS)和跨站请求伪造(CSRF)。通过 CORS(跨源资源共享),服务器可以明确指定哪些跨域请求是被允许的,客户端则会遵循 HTTP 协议中的安全规范,按照服务器的授权进行操作。当服务器明确允许跨域请求时,客户端会放行这些请求,从而顺利完成跨域访问。总之,客户端的跨域限制是为了遵循 HTTP 协议和 Web 安全标准,保障用户的隐私和数据安全。


客户端“自废武功”背后的深层秘密——CORS跨域是怎么回事?的更多相关文章

  1. Ajax跨域问题及解决方案 asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS) c#中的Cache缓存技术 C#中的Cookie C#串口扫描枪的简单实现 c#Socket服务器与客户端的开发(2)

    Ajax跨域问题及解决方案   目录 复现Ajax跨域问题 Ajax跨域介绍 Ajax跨域解决方案 一. 在服务端添加响应头Access-Control-Allow-Origin 二. 使用JSONP ...

  2. 使用Httpclient来替代客户端的jsonp跨域解决方案

    最近接手一个项目,新项目需要调用老项目的接口,但是老项目和新项目不再同一个域名下,所以必须进行跨域调用了,但是老项目又不能进行任何修改,所以jsonp也无法解决了,于是想到了使用了Httpclient ...

  3. 客户端调用web中js方法(C调B)跨域问题

    这几天遇到了个棘手问题(c调b),经过排错查出了问题. 一,问题描述如下: 1.客户端需要调用father.html中一个js方法,特殊之处在于 这个father.html中有个iframe嵌套了一个 ...

  4. 客户端ajax请求为实现Token验证添加headers后导致正常请求变为options跨域请求解决方法

    客户端为了实现token认证,通过Jquery的ajaxSetup方法全局配置headers: 全局配置headers后会导致部分不需要token认证的请求变为options请求,导致跨域访问.报错信 ...

  5. HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端

    HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端 发表时间:2020-03-05 1 ...

  6. html5客户端跨域访问php服务端数据

    客户端代码: var param = $.param( { feed:JSON.stringify({ content:'abcd' }) } ); $http({ url: 'http://61.1 ...

  7. 关于Lind.DDD.Api客户端的使用与知识分享

    回到目录 关于Lind.DDD.Api的使用与客户端的调用 作者:张占岭 花名:仓储大叔 框架:Lind.DDD,Lind.DDD.Api 目录 Api里注册全局校验特性 1 Api中设置全局的Cor ...

  8. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之二 || 后端项目搭建

    前言 至于为什么要搭建.Net Core 平台,这个网上的解释以及铺天盖地,想了想,还是感觉重要的一点,跨平台,嗯!没错,而且比.Net 更容易搭建,速度也更快,所有的包均有Nuget提供,不再像以前 ...

  9. Python面试笔记一

    目录 一.MySQL(30题) 二.django(15题) 三.Python部分(46题) 四.RESTful API设计指南(7题) 五.补充 一.MySQL(30题) 1.mysql如何做分页 m ...

  10. tornado框架&三层架构&MVC&MTV&模板语言&cookie&session

    web框架的本质其实就是socket服务端再加上业务逻辑处理, 比如像是Tornado这样的框架. 有一些框架则只包含业务逻辑处理, 例如Django, bottle, flask这些框架, 它们的使 ...

随机推荐

  1. 【Java 温故而知新系列】基础知识-02 数据基本类型

    1.Java基本数据类型 Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间. 基本数据类型 数值型:整数类型(byte,short,int,lon ...

  2. MTK8766 LK GPIO初始化状态设置分析

    问题来源是M.2 Dongle的LED灯在kernel起来之前就亮了,kernel起来之后又初始化成熄灭状态.通过排查硬件规格书.GPIO表格,大概判定是前期软件初始化不正确造成的.通过观察串口打印的 ...

  3. runoob-设计模式

    https://www.runoob.com/design-pattern/design-pattern-tutorial.html 设计模式(Design pattern)代表了最佳的实践,通常被有 ...

  4. Android平台架构及特性

    Android平台架构及特性 Android系统的底层是建立在Linux系统之上,改平台由操作系统.中间件.用户界面和应用软件四层组成,它采用一种被称为软件叠层(Software Stack)的方式进 ...

  5. w3cschool-Lua编程入门

    https://www.w3cschool.cn/nhycto/ https://www.w3cschool.cn/cf_web/cf_web-dvxc32qu.html 1. Lua 基础知识 (1 ...

  6. Mysql调优之使用mysql慢查询日志优化sql语句及表索引

    Mysql调优之使用mysql慢查询日志优化sql语句及表索引 一,用慢查询日志找出耗时语句,并优化 # 查看mysql系统慢查询变量配置(能看到慢查询日志是否开启,日志路径等) SHOW VARIA ...

  7. FailFast机制-抛出 java.util.ConcurrentModificationException(保证并发访问时集合的完整性,内部结构变化的防护措施)

  8. android studio编译flutter项目

    1创建flutter项目:如下图 2选择 flutter application 3 出现flutter SDK没有发现:但是自己又是安装了的 如果,忘记自己flutter安装在哪里的同学. 可以先找 ...

  9. 第2章 C# 语言基础

    第2章 C# 语言基础 难点提纲 mindmap 第2章 C#语言基础 数值类型 数值字面量 溢出检查 特殊的浮点值 decimal 舍入误差 数组 简化初始化的<br/>两种方式 变量和 ...

  10. 配置计算节点之间的SSH

    本文分享自天翼云开发者社区<配置计算节点之间的SSH>,作者:y****n 如果在管理程序之间调整或迁移实例,可能会遇到SSH(拒绝权限)错误.请确保每个节点都配置了SSH密钥验证,以便C ...