跨域问题解决方案之CORS

跨域问题解决方案之CORS

文章目录

  • 跨域问题解决方案之CORS
    • 概述
    • 浏览器的同源策略
      • 同源的判定规则
      • 目的
      • 同源策略的限制范围
    • 浏览器的同源策略为什么会引发跨域问题?
    • CORS规则
    • CORS解决方案
      • CORS方案将请求分为两类
      • 举例
      • 简单请求
      • 预检请求
      • 总结
      • 学以致用

概述

  • 浏览器安全的基石是"同源政策"(same-origin policy)。
  • 1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。

浏览器的同源策略

同源的判定规则

  • 它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。

    • 协议相同
    • 域名相同
    • 端口相同
  • 如果两个 URL 的 协议端口(如果有指定的话)和 域名 都相同的话,则这两个 URL 是同源的。

  • 下表给出了与 URL http://store.company.com/dir/page.html 的源进行对比的示例:

URL结果原因
http://store.company.com/dir2/other.html同源只有路径不同
http://store.company.com/dir/inner/another.html同源只有路径不同
https://store.company.com/secure.html失败协议不同
http://store.company.com:81/dir/etc.html失败端口不同(http:// 默认端口是 80)
http://news.company.com/dir/other.html失败主机不同

目的

  • 同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
  • 设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?
  • 很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
  • 由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。

同源策略的限制范围

  • 随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。
    • CookieLocalStorageIndexDB 无法读取。
    • DOM 无法获得。
    • AJAX 请求不能发送。

浏览器的同源策略为什么会引发跨域问题?

  • 请求发出 -> 响应 -> 浏览器会有个校验
  • 当浏览器校验通过的时候,就不会有跨域的问题
  • 当浏览器校验不通过的时候,就会引发跨域的问题
  • 这个校验的规则就叫做CORS规则
  • 所以,我们要做的就是让浏览器通过这个校验,也就没有跨域的问题了。而我们要让浏览器通过校验,就必须要了解CORS规则。

在这里插入图片描述

CORS规则

  • CORS全称:Cross-Origin Resource Sharing,中文翻译为:跨源资源共享 或 跨域资源共享。
  • CORS是一种基于 HTTP 头的机制,用于浏览器校验跨域请求。
  • 它的基本理念是:
    • 只要 服务器 明确表示 允许 ,则校验 通过
    • 服务器 明确 拒绝没有表示 ,则校验 不通过
  • 从原则中,我们可以看出,要用CORS来解决跨域问题,主要靠服务器来解决,也就是后端。
  • 使用CORS方案的前提,必需保证服务器是自己人。

CORS解决方案

  • 跨域的解决方案有很多,但是CORS是最正统的解决方案,也是官方推荐使用的方案。

CORS方案将请求分为两类

  • CORS方案将请求分为两类:
    • 简单请求(Simple requests),若请求满足所有下述条件,则该请求可视为简单请求:

      • 请求方法为之一:GETHEADPOST
      • 头部字段满足CORS安全规范,详见 W3C。简单来说只要我们不去改动请求的头部,就是满足安全规范的。
      • 请求头的Content-Type为下面三个中的一个:
        • text/plain
        • multipart/form-data
        • application/x-www-form-urlencoded
    • 预检请求(Preflight request / Preflighted requests)

      • 只要不是简单请求的都是预检请求
      • “需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。

举例

  • 举例说明哪些是简单请求,哪些是预检请求

    // 简单请求: GET请求、没有改动请求头、没有改动Content-Type
    fetch('https://douyin.com');// 预检请求: 改动了请求头
    fetch('https://douyin.com', {headers: {a: 1,},
    });// 简单请求: POST请求、没有改动请求头、没有改动Content-Type
    fetch('https://douyin.com', {method: 'POST',body: JSON.stringify({a: 1, b: 2})
    });// 预检请求: 改动了Content-Type不满足第三个要求
    fetch('https://douyin.com', {method: 'POST',headers: {'content-type': 'application/json'}body: JSON.stringify({a: 1, b: 2})
    })
    

简单请求

在这里插入图片描述

  • 在发送请求的时候,浏览器发现跨域了,会自动带上一个请求头,这是自动的,我们不用管,我们也改不了,就是OriginOrigin表达的是当前的页面源,即从哪个源发送了这个跨域请求。
  • 此时服务器收到该请求发现http://my.com是自己人,此时服务器就要告诉浏览器你别管了这是自己人。服务器告诉浏览器这是自己人的方式有两种方案:
    • 第一种方案:设置一个响应头Access-Control-Allow-Origin并跟上这个源。只要这个源和当前的页面源保持一致,那么浏览器就知道服务器已经明确表示允许,则浏览器校验通过。
    • 第二种方案:设置响应头Access-Control-Allow-Origin*,这会告诉我浏览器:服务器对所有源都通过,那么浏览器也会校验通过。

预检请求

在这里插入图片描述

  • 当发送为非简单请求,即预检请求的时候,浏览器会引起高度重视。
    所以在第一步不会真实的发生这个请求,而是先发送一个询问给服务器(浏览器会先问一下服务器:哥们,我这边现在有个页面源在跨域请求你,我担心这个动作有危险,我先问一下你行不行,如果你告诉我行,我再发真实的请求给你)。
  • 所以,实际上第一步会发送一个预检请求向服务器进行询问,预检请求的请求方法为OPTIONS,然后会带上3个请求头参数
    • Origin:表达的是当前的页面源,即从哪个源发送了这个跨域请求。
    • Access-Control-Request-Method:用什么样的请求方法在请求。
    • Access-Control-Request-Headers:这次的请求改动了哪些请求头。
  • 当服务器收到OPTIONS的预检请求后,如果服务器说没问题,那么服务器会返回
    • Access-Control-Allow-Origin:服务器告诉浏览器我允许的源。
    • Access-Control-Allow-Methods:服务器告诉浏览器我允许的请求方法,可以是多个。
    • Access-Control-Allow-Headers:服务器告诉浏览器我允许的请求头是包含哪些的
    • Access-Control-Max-Age:服务器告诉浏览器只要是在86400秒内,只要是来自于Origin内的这个源的请求你都不要再重复的问我了,我都是这一套回答,你可以把它缓存起来。

在这里插入图片描述

  • 通过了预检请求之后,然后再进入第二部发送真实的请求,此时就和普通请求也就是简单请求是完全一样的了。

总结

  • CORS方案,服务器处理的逻辑就是按照浏览器的这套规范,对相应的头部做出设置即可。

学以致用

  • 领导让前端小王使用CORS在页面上自行解决跨域的问题。前端小王可以完成要求吗?
    • 不能。因为CORS是要动服务器的。
  • 前端小王在页面中想使用AJAX调用抖音的API接口,却发生了跨域的问题。小王想通过CORS来解决这个问题。前端小王可以解决吗?
    • 不能。必须要保证服务器是自己人。
  • 跨域上传图片没有问题,但是提交普通表单却遇到了跨域问题。前端小王仔细分析后,认为是服务器不支持预检请求导致的。前端小王分析的结果有可能发生吗?
    • 完全有可能。
      因为上传图片用的是POST请求方法,用的Content-Typemultipart/form-data,所以上传图片很有可能是一个简单请求。
      而提交普通表单可能是一个ajax,而通常在公司里,大部分使用json格式发过去的,这就要把Content-Type改成application/json,这样就变成了预检请求,那么预检请求遇到跨域问题就有可能是服务器支持简单请求,不支持预检请求导致的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

esp32控制舵机---待完善

舵机有三个引脚,分别是电源、电源GND和信号线。如下图所示: ESP32-WROOM-32E的引脚的定义如下: 图来自乐鑫官网:ESP32-DevKitC V4 入门指南 - ESP32 - — ESP-IDF 编程指南 v5.2.1 文档 硬件连接图: 待补充

Failed to resolve import “Home/components/HomeNew.vue“. Does the file exist?

错误信息 [plugin:vite:import-analysis] Failed to resolve import "/apis/home.js" from "src/views/Home/components/HomeNew.vue". Does the file exist? 错误原因 路径错误 解决方法

面试复盘1 - 测试相关(实习)

写在前:hello,大家早中晚上好~这里是西西,最近有在准备测试相关的面试,特此开设了新的篇章,针对于面试中的问题来做一下复盘,会把我自己遇到的问题进行整理,除此之外还会进行对一些常见面试题的…

蓝桥杯算法题:区间移位

题目描述 数轴上有n个闭区间&#xff1a;D1,...,Dn。 其中区间Di用一对整数[ai, bi]来描述&#xff0c;满足ai < bi。 已知这些区间的长度之和至少有10000。 所以&#xff0c;通过适当的移动这些区间&#xff0c;你总可以使得他们的“并”覆盖[0, 10000]——也就是说[0, 100…

动态规划详解(Dynamic Programming)

目录 引入什么是动态规划&#xff1f;动态规划的特点解题办法解题套路框架举例说明斐波那契数列题目描述解题思路方式一&#xff1a;暴力求解思考 方式二&#xff1a;带备忘录的递归解法方式三&#xff1a;动态规划 推荐练手题目 引入 动态规划问题&#xff08;Dynamic Progra…

【并发编程系列】使用 CompletableFuture 实现并发任务处理

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

Autodesk AutoCAD 2025 (macOS, Windows) - 自动计算机辅助设计软件

Autodesk AutoCAD 2025 (macOS, Windows) - 自动计算机辅助设计软件 AutoCAD 2024 开始原生支持 Apple Silicon&#xff0c;性能提升至 2 倍 请访问原文链接&#xff1a;https://sysin.org/blog/autodesk-autocad/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处…

Golang | Leetcode Golang题解之第8题字符串转换整数atoi

题目&#xff1a; 题解&#xff1a; func myAtoi(s string) int {abs, sign, i, n : 0, 1, 0, len(s)//丢弃无用的前导空格for i < n && s[i] {i}//标记正负号if i < n {if s[i] - {sign -1i} else if s[i] {sign 1i}}for i < n && s[i] >…

Spark-Scala语言实战(9)

之前的文章中&#xff0c;我们学习了如何在spark中使用RDD方法的flatMap,take,union。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&am…

【ESP32S3 Sense接入语音识别+MiniMax模型+TTS模块语音播报】

【ESP32S3 Sense接入语音识别MiniMax模型TTS模块语音播报】 1. 前言2. 功能模块概述2.1 语音接入2.2 大模型接入2.3 TTS模块接入 3. 先决条件3.1 环境配置3.2 所需零件3.3 硬件连接步骤 4. 核心代码4.1 源码分享4.2 代码解析 5. 上传验证5.1 对话测试5.2 报错 6. 总结 1. 前言 …

C语言杂谈

努力扩大自己&#xff0c;以靠近&#xff0c;以触及自身以外的世界 文章目录 什么是定义&#xff1f;什么是声明&#xff1f;什么是赋值&#xff1f;什么是初始化&#xff1f;什么是生命周期&#xff1f;什么是作用域&#xff1f;全局变量&#xff1f;局部变量&#xff1f;size…

HCIA-RS基础-VLAN路由

目录 VLAN 路由1. 什么是 VLAN 路由2. VLAN 路由的原理及配置3. VLAN 的缺点和 VLAN Trunking4. 单臂路由配置 总结 VLAN 路由 1. 什么是 VLAN 路由 VLAN 路由是指在虚拟局域网&#xff08;VLAN&#xff09;之间进行路由转发的过程。传统的 VLAN 配置只能在同一个 VLAN 内进行…

LCD1602显示屏

LCD1602显示 概述 LCD1602&#xff08;Liquid Crystal Display&#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符(16列两行) 引脚说明 //电源 VSS -- GND VDD -- 5V //对比度 VO -- GND //控制线 RS -- P1.0 RW -- P1.1 E -- P1.4 //背光灯 A -- 5…

在ChatGPT中,能用DALL·E 3编辑图片啦!

4月3日&#xff0c;OpenAI开始向部分用户&#xff0c;提供在ChatGPT中的DALLE 3图片编辑功能。 DALLE 3是OpenAI在2023年9月20日发布的一款文生图模型&#xff0c;其生成的图片效果可以与Midjourney、leonardo、ideogram等顶级产品媲美&#xff0c;随后被融合到ChatGPT中增强其…

matlab的歧视:simulink不能使用stm32f4系列的ADC?

2023b的matlab&#xff0c;stm32f407芯片&#xff0c;运行内容Using the Analog to Digital Converter Block to Support STMicroelectronics STM32 Processor Based Boards Using the Analog to Digital Converter Block to Support STMicroelectronics STM32 Processor Base…

基于SSM的社区疫情防控管理信息系统

目录 背景 技术简介 系统简介 界面预览 背景 随着时代的进步&#xff0c;计算机技术已经全方位地影响了社会的发展。随着居民生活质量的持续上升&#xff0c;人们对社区疫情防控管理信息系统的期望和要求也在同步增长。在社区疫情防控日益受到广泛关注的背景下&#xff0c…

【漏洞复现】通天星CMSV6车载主动安全监控云平台inspect_file接口处存在任意文件上传漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

电商技术揭秘一:电商架构设计与核心技术

文章目录 引言一、电商平台架构概述1.1 架构设计原则与架构类型选择1.2 传统电商平台架构与现代化架构趋势分析 二、高并发处理与负载均衡2.1 高并发访问特点分析与挑战2.2 负载均衡原理与算法选择 三、分布式数据库与缓存技术3.1 分布式数据库设计与一致性考量3.2 缓存策略与缓…

基于SpringBoot和Vue的金融融资管理系统的设计和实现【附源码】

1、系统演示视频&#xff08;演示视频&#xff09; 2、需要交流和学习请联系

vue弹出的添加信息组件中 el-radio 单选框无法点击问题

情景描述:在弹出的添加信息的组件中的form中有一个单选框,单选框无法进行点击切换 原因如下: 单选框要求有个默认值,因为添加和更新操作复用同一个组件,所以我在初始化时对相关进行了判定,如果为空则赋初始值 结果这样虽然实现了初始值的展示,但是就是如此造成了单选框的无法切…