解决CORS问题的技术点的原理总结

news2024/11/15 10:35:56

序言-引出问题

本人在毕业之后主要是从事游戏开发的客户端相关工作,由于游戏引擎的跨平台功能,所以在游戏开发完成之后,需要发布的平台经常会包含Web平台(包括desktop Web、Mobile Web)。

打包出来的项目文件的入口都是index.html文件。

但是如果直接双击打开index.html之后,在浏览器上是运行不起来的,都会报以下类似的错误

其中,主要关注这个错误:

from origin 'null' has been blocked by CORS policy

 这个错误引发两个关键点。

origin 'null'

CORS policy

这里首先要解释“CORS”,再解释“origin ''null'”。

CORS

先来个官方解释:

CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种安全机制,防止非同源的域进行数据交互。出现这个错误通常意味着你的前端应用尝试从一个与其自身不同源的域(origin)获取资源,但该域没有明确地给予允许。

 好的,又是一长串用概念拼接起来的文字,读起来费劲。

那么我们再来找重点——非(不)同源的域(origin)

为什么需要有CORS

在接触一项我们之前没有了解的技术的时候,我们都应该有一个习惯,那就是问一下为什么会需要这个技术

在CORS的解释中,已经说出CORS是为了防止非同源的域进行数据交互,是一种安全机制。

那么了解为什么会有CORS,就要了解在没有CORS之前,怎么处理跨域问题。

在没有CORS之前,主要是使用JSONP来解决跨域的问题。

那么我们先来了解JSONP大概是怎么样的:

  • JSONP是一种利用 <script> 标签进行跨域请求的技术,不是一种数据格式。
  • JSONP主要用于解决浏览器同源策略限制下的跨域问题,允许从不同域的服务器获取数据。
  • JSONP通过在URL中指定一个回调函数名(padding),服务器在响应时将数据包裹在该函数的调用中返回,从而使得浏览器能够执行该回调函数并获取数据。
  • 示例: 如果请求的URL为 http://example.com/data?callback=myCallback,服务器返回的响应可能是 myCallback({"name": "John", "age": 30}),浏览器会执行 myCallback 函数,并传入数据作为参数。

其实我对JSONP也不是很了解,以上的内容主要来自网站搜索(如果大家对为什么有JSONP还感兴趣的话,可以自行查阅相关资料)。

那么为什么CORS可以替代JSONP才处理跨域的问题,CORS对比JSONP,有什么优点。

  • 安全性高:CORS 是浏览器提供的一种机制,通过设置 HTTP 头部来允许跨源请求。它的设计目标是保护用户的安全,避免恶意网站利用跨域请求进行攻击。

  • 支持多种 HTTP 方法:CORS 支持所有类型的 HTTP 请求,包括 GET、POST、PUT、DELETE 等,因此更加灵活。

  • 支持多种数据格式:CORS 不仅支持 JSON 数据,还支持其他类型的资源和数据格式,如 XML、HTML 等。

  • 规范化:CORS 是 W3C 标准的一部分,得到了广泛的支持和推广,成为了现代 Web 应用开发中处理跨域问题的首选解决方案。

其中主要注意支持多种HTTP方法。所以现代 Web 应用程序中,特别是使用 Ajax 请求和 API 访问时,推荐使用 CORS。它安全、灵活,并且符合现代 Web 标准。

怎么才算不同源(跨域)

所谓不同源,就引出了在Web的开发中,一个经常出现的词,那就是“跨域”。

那么这个域怎么才算同源,怎么才算不同源。

是否同源由CORS的同源策略决定。CORS的同源策略

同源策略的判断规则:

  1. 协议(Protocol)

    • 两个 URL 的协议部分必须完全相同(例如都是 http 或者都是 https)。
  2. 域名(Host)

    • 两个 URL 的主机名部分(域名部分)必须完全相同(例如 www.example.comapi.example.com 不同源)。
  3. 端口(Port)

    • 如果 URL 包含端口号,则两个 URL 的端口号必须完全相同(例如 http://example.com:80http://example.com:8080 不同源)。
    • 如果 URL 没有明确指定端口号,默认端口号为 80http)和 443https)。

只要其中一个同源条件不符合,那么就判定为跨域(即不同源)。

origin 'null'

再来说说这个词的意思,origin 'null'可能表示请求的来源是非明确的或未知的,这可能是因为请求没有正确地设置Origin头部,或者是因为请求是从本地文件系统(file://)发起的。

所以这个解释就符合我们前面双击打开文件这个操作。

如何解决

解决web页面部署跨域的方法可以分为两类,一、需要前端来解决;二、服务器来解决

前端来解决

由前端来解决的问题类型

有以下几种问题是由前端来解决的:

  • System.import

    • System.import(或 import(),ES6 动态导入)这个接口,和其他的 JavaScript 接口和情况也会触发 CORS(跨源资源共享)问题。
  • 动态脚本加载跨域问题

    • 动态创建 <script> 标签加载跨域脚本时,同样受到浏览器的同源策略限制。可以考虑使用 JSONP 或 CORS 解决方案。
  • AJAX 请求跨域问题

    • 使用 XMLHttpRequest 或 Fetch API 发起跨域请求时,需要处理浏览器的同源策略限制。解决方法包括使用 CORS、JSONP、代理服务器等。
  • Cookies 跨域问题

    • 默认情况下,浏览器不会发送跨域请求的 Cookie。如果需要在跨域请求中发送和接收 Cookie,需要在服务器端设置 Access-Control-Allow-Credentialstrue,并在客户端设置 withCredentialstrue
  • LocalStorage 和 IndexedDB 跨域问题

    • 虽然这些本地存储机制通常不直接受到 CORS 的影响,但如果跨域请求获取数据并存储在本地存储中,可能需要考虑安全性和数据隔离的问题。
  • 前端框架或库中的跨域支持

    • 一些前端框架或库可能会提供跨域请求的封装或支持,开发人员需要了解和使用这些功能来简化跨域请求的处理。

其中经常出现的是前三种情况 ,在文章开头的问题就是第二种动态脚本加载跨域问题

那么如何解决前端如何解决以上类型的问题呢?主要有以下两种方式:

  • 使用代理服务器

    • 如果直接在客户端无法修改请求或处理CORS问题,可以考虑在客户端和服务端之间部署代理服务器。代理服务器可以在服务器端发送请求,然后将响应返回给客户端,避免跨域限制。
  • 使用JSONP

    • 对于仅支持 GET 请求的跨域数据获取,可以考虑使用 JSONP。JSONP 利用 <script> 标签没有跨域限制的特性,通过动态创建 <script> 标签来加载数据。

 其中使用代理服务器是最为常见的解决方案,代理服务器又分为正向代理服务器、反向代理服务器、Web服务器等。

其中反向代理服务器又是最为常见的代理服务器,而反向代理服务器又有Nginx、Apache等。

其中Nginx又是最为常见的反向代理服务器,所以我们需要把我们的html页面及所有资源都部署到Nginx的服务器上面去。

Nginx如何解决CORS

Nginx的概念

Nginx同Apache一样都是一种Web 服务器、反向代理服务器,也可以用作负载均衡器和 HTTP 缓存。

Nginx基于REST架构风格,以统一资源描述符(Uniform Resources Identifier)URI 或者 统一资源定位符(Uniform Resources Locator)URL 作为沟通依据,通过 HTTP 协议提供各种网络服务。

由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。

Nginx解决CORS的方法

Nginx可以解决CORS(跨源资源共享)问题,主要是因为它作为反向代理服务器,具有灵活的配置能力和强大的请求处理功能。以下是几个关键原因:

  1. 添加HTTP响应头: Nginx可以通过配置文件中的add_header指令,动态地添加HTTP响应头。对于CORS来说,主要是通过添加Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers等头部来告知浏览器哪些源、方法和头部是允许的。这使得Nginx能够在代理请求时向响应中注入必要的CORS头部信息。

  2. 处理预检请求(OPTIONS请求): 跨源请求中,浏览器在发送一些特殊类型的请求(如带有自定义头部的请求或非简单请求)之前,会发送一个预检请求(OPTIONS请求)。Nginx能够通过配置在收到这类请求时,正确响应预检请求,包括返回允许的方法、头部等信息,从而使浏览器在正式发送实际请求前获得必要的确认。

  3. 灵活的位置和服务器块配置: Nginx的配置文件允许在不同的位置块(location block)或服务器块(server block)中针对不同的URL路径或虚拟主机配置CORS。这种灵活性使得可以根据需要细粒度地控制CORS策略,以满足不同的业务需求和安全要求。

  4. 性能和可扩展性: Nginx因其高性能和低资源消耗而广受欢迎,能够处理大量并发请求。通过在Nginx层面解决CORS问题,可以减少后端服务器的负担,提高整体系统的性能和可扩展性。

综上所述,Nginx作为反向代理服务器,具备处理HTTP请求和响应的强大功能,使其能够有效地解决CORS问题。通过正确配置CORS相关的HTTP头部和处理预检请求,Nginx能够帮助应用程序和服务在跨源请求中实现安全、可靠的数据交换。

Tips:关于Nginx的更多内容,请自行查询。

服务器来解决

由服务器来解决的问题来源

在正常的Web页面开发流程中,有两个概念比较重要,第一是Web页面的资源地址,第二是Web页面请求接口的服务器地址。

Web页面的资源链接地址往往与Web页面请求接口的服务器地址不一致。

这就是造成这一类CORS问题的主要来源。

服务器解决CORS问题主要方法

服务器通过以下方法来处理CORS(在Go、Java、NodeJs都适用)。

第一、设置Access-Control-Allow-Origin头部

  • 这是最基本的CORS响应头部。通过设置Access-Control-Allow-Origin头部,可以指定允许访问资源的域名或使用通配符 * 表示允许所有域名访问。例如,允许所有域名访问可以这样设置:

Access-Control-Allow-Origin: *

或者指定具体的域名:

Access-Control-Allow-Origin: https://example.com

第二、处理预检请求(OPTIONS请求)

  • 对于某些复杂请求(例如带有自定义头部或使用非简单 HTTP 方法的请求),浏览器会先发送一个 OPTIONS 请求(预检请求)。服务器需要正确响应这个预检请求,包括返回适当的CORS头部和响应状态码(如200 OK)。
  • 设置 Access-Control-Allow-Methods 头部指定允许的 HTTP 方法,如 GET, POST, PUT, DELETE 等。
  • 设置 Access-Control-Allow-Headers 头部指定允许的 HTTP 头部,例如 Content-Type, Authorization 等。

第三、允许发送 Cookie 和 HTTP 认证信息

  • 如果跨域请求需要发送和接收 Cookie 或 HTTP 认证信息,服务器需要设置 Access-Control-Allow-Credentials: true 头部,并在客户端请求中设置 credentials: 'include'

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

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

相关文章

《书生大模型实战营第3期》入门岛 学习笔记与作业:Python 基础知识

文章大纲 Python 简介1 安装Python1.1 什么是conda&#xff1f;1.1.1 功能与作用&#xff1a;1.1.2 常用命令&#xff1a;1.1.3 适用性&#xff1a; 1.2 Python安装与学习环境准备1.2.1 下载miniconda1.2.2 安装miniconda1.2.3 创建一个python练习专属的conda虚拟环境 2: Pytho…

C++第十弹 ---- vector的介绍及使用

目录 前言vector的介绍及使用1. vector的使用1.1 vector的定义1.2 iterator的使用1.3 vector空间增长问题1.4 vector增删查改 2. vector迭代器失效问题(重点) 总结 前言 本文介绍了C中的vector数据结构及其使用方法。 更多好文, 持续关注 ~ 酷酷学!!! 正文开始 vector的介绍…

【Linux】文件系统|CHS寻址|LBA逻辑块|文件索引|inode|Date block|inodeBitmap|blockBitmap

前言 一个进程通过文件描述符标识一个打开的文件&#xff0c;进程拿着文件描述符可以在内核中找到目标文件进行读写等操作。这是打开的文件&#xff0c;而没有被打开的文件存储在磁盘中&#xff0c;是如何管理的&#xff1f;操作系统在偌大的磁盘中如何找到想要的文件并打开的…

数据传输安全--SSL VPN

目录 IPSEC在Client to LAN场景下比较吃力的表现 SSL VPV SSL VPN优势 SSL协议 SSL所在层次 SSL工作原理 SSL握手协议、SSL密码变化协议、SSL警告协议三个协议作用 工作过程 1、进行TCP三次握手、建立网络连接会话 2、客户端先发送Client HELLO包&#xff0c;下图是包…

目标检测 | YOLO v4、YOLO v5、YOLO v6理论讲解

☀️教程&#xff1a;霹雳吧啦Wz ☀️https://space.bilibili.com/18161609/channel/seriesdetail?sid244160 一、YOLO v4 YOLO v4在2020年的4月发布&#xff0c;YOLO v4结合了大量的前人研究技术加以组合&#xff0c;实现了速度和精度的平衡&#xff0c;该论文包含大量的tric…

二叉树 N0=N2+1

N0 叶子节点&#xff0c;度为 0 的节点&#xff1b; N1 度为 1 的节点&#xff1b; N2 度为 2 的节点 度为 0 的节点为&#xff1a;H、I、J、K、G 度为 1 的节点&#xff1a;E、F 度为 2 的节点&#xff1a;A、B、D、C N0 N2 1&#xff0c;即&#xff1a;度为 0 的叶子节点 …

C++STL详解(一)——string类的接口详解(下)

目录 一.string的大小和容量成员函数 1.1size()和length() 1.2capacity() 1.3resize() 1.4reserve() 1.5clear()和empty() ​编辑 二.string元素的访问 2.1operator[]和at() 2.2范围for 三.string中迭代器相关函数 3.1begin()和end() 3.2rbegin()和rend() 四.string…

Anaconda +Pytorch安装教程

Anaconda Pytorch安装教程 Anaconda安装 小土堆的安装教程&#xff1a;PyTorch深度学习快速入门教程&#xff08;绝对通俗易懂&#xff01;&#xff09;【小土堆】_哔哩哔哩_bilibili Free Download | Anaconda 这里自己选一个文件夹安装即可 第一个红框表示添加图标到开始菜…

细说MCU用自带的波形发生器实现DAC输出的方法

目录 一、参考示例 二、配置参数 1.配置DAC 2.配置TIM3 三、代码修改 四、查看结果 DAC模块自带的硬件波形发生器只有三角波(Triangle wave)和 (Noise wave)两种。此外&#xff0c;如果配置了Trigger2参数&#xff0c;在波形发生模式中就出现(并且仅出现)锯齿波的选项(Sa…

Codeforces Round 874 (Div. 3)(A~D题)

A. Musical Puzzle 思路: 用最少的长度为2的字符串按一定规则拼出s。规则是&#xff1a;前一个字符串的尾与后一个字符串的首相同。统计s中长度为2的不同字符串数量。 代码: #include<bits/stdc.h> #include <unordered_map> using namespace std; #define N 20…

vue3前端开发-小兔鲜项目-登录功能的业务接口调用

vue3前端开发-小兔鲜项目-登录功能的业务接口调用!这次&#xff0c;正式调用远程服务器的登录接口了。大家要必须使用测试账号密码&#xff0c;才能验证我们的代码。 测试账号密码是&#xff1a;账号&#xff08;xiaotuxian001&#xff09;&#xff1b;密码是&#xff08;1234…

【python】sklearn基础教程及示例

【python】sklearn基础教程及示例 Scikit-learn&#xff08;简称sklearn&#xff09;是一个非常流行的Python机器学习库&#xff0c;提供了许多常用的机器学习算法和工具。以下是一个基础教程的概述&#xff1a; 1. 安装scikit-learn 首先&#xff0c;确保你已经安装了Python和…

什么是hdfs如何使用驱动程序访问hdfs

目录 什么是hdfs 主要特点包括&#xff1a; 架构组成&#xff1a; 应用场景&#xff1a; 如何使用驱动程序访问hdfs 准备工作环境&#xff1a; 启动 Hadoop 服务 可能遇到的问题&#xff1a; ssh验证失败 验证Hadoop服务 对hdfs进行文件操作 什么是hdfs HDFS&#x…

【数据结构】栈(基于数组、链表实现 + GIF图解 + 原码)

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

Linux--Socket 编程 UDP(简单的回显服务器和客户端代码)

目录 0.上篇文章 1.V1 版本 - echo server 1.1认识接口 1.2实现 V1 版本 - echo server&#xff08;细节&#xff09; 1.3添加的日志系统&#xff08;代码&#xff09; 1.4 解析网络地址 1.5 禁止拷贝逻辑&#xff08;基类&#xff09; 1.6 服务端逻辑 &#xff08;代码&…

Leetcode—769. 最多能完成排序的块【中等】

2024每日刷题&#xff08;149&#xff09; Leetcode—769. 最多能完成排序的块 实现代码 class Solution { public:int maxChunksToSorted(vector<int>& arr) {int ans 0;int mx INT_MIN;for(int i 0; i < arr.size(); i) {mx max(arr[i], mx);if(mx i) {a…

【C++】C++应用案例-旋转图像

旋转图像的需求&#xff0c;在图片处理的过程中非常常见。我们知道对于计算机而言&#xff0c;图像其实就是一组像素点的集合&#xff0c;所以图像旋转的问题&#xff0c;本质上就是一个二维数组的旋转问题。 我们可以给定一个二维数组&#xff0c;用来表示一个图像&#xff0c…

【C++】——红黑树(手撕红黑树,彻底弄懂红黑树)

目录 前言 一 红黑树简介 二 为什么需要红黑树 三 红黑树的特性 四 红黑树的操作 4.1 变色操作 4.2 旋转操作 4.3 插入操作 4.4 红黑树插入代码实现 4.5 红黑树的删除 五 红黑树迭代器实现 总结 前言 我们之前都学过ALV树&#xff0c;AVL树的本质就是一颗平…

Oracle对比两表数据的不一致

MINUS 基本语法如下 [SQL 语句 1] MINUS [SQL 语句 2];举个例子&#xff1a; select 1 from dual minus select 2 from dual--运行结果 1-------------------------------- select 2 from dual minus select 1 from dual--运行结果 2所以&#xff0c;如果想找所有不一致的&a…

软件测试---Linux

Linux命令使用&#xff1a;为了将来工作中与服务器设备进行交互而准备的技能&#xff08;远程连接/命令的使用&#xff09;数据库的使用&#xff1a;MySQL&#xff0c;除了查询动作需要重点掌握以外&#xff0c;其他操作了解即可什么是虚拟机 通过虚拟化技术&#xff0c;在电脑…