跨域问题的原理及解决方法

news/2025/3/14 18:06:08/

一.同源策略

如果没有进行特殊处理,我们在进行前后端联调的时候游览器会发生报错:

这是因为请求被同源策略被阻止,浏览器出于安全的考虑,使用XMLHttpRequest对象发起HTTP请求(异步请求)时必须遵守同源策略,否则就是跨域的HTTP请求,默认情况下是被禁止的。

那什么是同源策略呢?

同源策略(Same-Origin Policy),是一个web安全的基础原则。

【1】同源

什么是同源呢?指的是协议(如HTTP或HTTPS)、域名和端口号完全相同才算同源。

【2】跨域

从一个地址请求另一个地址,如果协议、主机、端口三者全部一致则不属于跨域(CORS--cross origin resource share 跨域资源共享),否则有一个不一致就是跨域请求,即不同源就是跨域。

【3】同源策略

而跨域的请求如果没对服务端做特殊处理,默认情况下游览器的请求是无法访问成功的。这就是游览器的同源策略。【同源策略要求在浏览器中运行的脚本只能访问和自身来源相同的文档或脚本】

在游览器中进行前后端联调的时候,本地的端口号与游览器中网页的协议一致,主机一致,但是端口号不一致,所以就会请求接口服务失败。这就是违反了同源策略,产生了跨域问题。所以游览器请求本地接口会失败。

注:为什么Postman没有跨域问题呢?因为Postman不是游览器,没有同源策略。

二.跨域请求的原理

在普通的跨域请求中(非简单请求),浏览器会先发送一个 OPTIONS 请求,该请求称为预检请求(preflight request),用来检查是否允许跨域访问。服务器收到预检请求后,根据请求中的头部信息进行判断,并返回相应的响应头,表示是否允许跨域访问。如果服务器返回的响应头中包含了允许跨域的信息(返回Access-Control-Allow-Origin 头信息),浏览器才会发送实际的跨域请求。

如果服务器没有正确设置响应头,或者返回的响应头中不包含允许跨域的信息,浏览器会拦截跨域请求,导致请求失败。

另外,需要注意的是浏览器的同源策略限制只存在于浏览器环境中。只有游览器才有跨域请求,如果在服务器端进行跨域请求,是不受同源策略限制的。

同源策略的作用是防止恶意网站通过在其页面中注入恶意脚本并获取其他来源的数据,防止跨站点脚本攻击(Cross-Site Scripting,XSS)、跨站点请求伪造(Cross-Site Request Forgery,CSRF)等安全问题的发生。

三.解决跨域问题的方法

那我们怎么让跨域请求成功发送呢?

1.JSONP--了解一下

通过script标签的src属性进行跨域请求,如果服务端要响应内容则首先读取请求参数callback的值,callback是一个回调函数的名称,服务端读取callback的值后将响应内容通过调用callback函数的方式告诉请求方。如下图:

2.添加响应头--常用

服务端在响应头添加 Access-Control-Allow-Origin:*,这样浏览器才会发送实际的跨域请求

原理:

实现:

【1】添加@CrossOrigin注解

既可以用在controller层方法上,表示让这个controller层的接口允许跨域,也可以用在controller层的该类中所有接口允许跨域

【2】在springboot中添加跨域配置类

(实现的原理就是在响应头添加Access-Control-Allow-Origin)

@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry){//设置允许跨域的路径registry.addMapping("*")//是否允许cookie.allowCredentials(true)//设置允许的请求方式.allowedMethods("GET","POST","DELETE","PUT")//设置允许的header属性.allowedHeaders("*")//跨域允许时间.maxAge(3600);}
}

3.通过nginx代理跨域

简单说以前是直接访问服务器,现在是先访问nginx再由nginx访问服务器。nginx相当于代理,因为nginx不是游览器,所以没有跨域的问题,通过这样子就解决了跨域的问题。


http://www.ppmy.cn/news/1126429.html

相关文章

代码随想录算法训练营第四十二天 | 动态规划 part 4 | 01背包问题(二维、一维滚动数组)、416. 分割等和子集

目录 01背包问题 二维代码 01背包问题(一维滚动数组)代码 416. 分割等和子集思路代码 01背包问题 二维 背包问题汇总: 二维数组dp——01背包五部曲 dp[i][j]表示从下标为[0-i]的物品里面任意取,放进容量为j的背包,价值…

配置pytorchGPU虚拟环境-python3.7

cuda版本的pytorch包下载地址戳这里 winR->输入cmd->输nvcc -V回车 cuda 11.0 输入以下命令来查找 CUDA 的安装路径: Windows: where nvcc 输入以下命令来查找 cuDNN 的版本号: Windows: where cudnn* cuDNN 8.0 本机安装的是cuda 11.0&…

企业如何寻找可替代serv-u的国产文件传输系统?

serv-u是一款基于FTP协议的文件传输软件,它可以在Windows和Linux平台上运行,支持FTP、FTPS、SFTP、HTTP和HTTPS等多种传输协议,提供了图形化的管理界面和丰富的配置选项,可以满足不同用户的文件传输需求。但随着企业对于文件传输的…

SpringBoot之文件上传(单文件与多文件上传的使用)

文章目录 前言文件上传总结 前言 SpringBoot的单文件、多文件上传。 文件上传 页面代码/static/form/form_layouts.html <form role"form" th:action"{/upload}" method"post" enctype"multipart/form-data"><div class&q…

numpy的基础操作

numpy 创建:array import numpy as np anp.([[1,2,3],[4,6,2]]) anp.([[3,4,5]],dtypenp.int)#说明是int型的元素类型&#xff0c;默认是64位&#xff0c;或者可以dtypenp.float anp.zeros((3,4))#创建三行四列的零矩阵 anp.ones((3,4))dtype可以规定创建的数据类型即可创建二…

Linux入门教程||Shell echo命令||Shell printf 命令

Shell 的 echo 指令与 PHP 的 echo 指令类似&#xff0c;都是用于字符串的输出。命令格式&#xff1a; echo string您可以使用echo实现更复杂的输出格式控制。 1.显示普通字符串: echo "It is a test"这里的双引号完全可以省略&#xff0c;以下命令与上面实例效果一…

MQ - 32 基础功能:消息查询的设计

文章目录 导图概述什么时候会用到消息查询消息队列支持查询的理论基础消息数据存储结构关于索引的一些知识点内核支持简单查询根据 Offset 查询数据根据时间戳查询数据根据消息 ID 查询数据借助第三方工具实现复杂查询第三方引擎支持查询工具化简单查询总结导图 概述 从功能上…

探索轻量级模型性能上限,基于GhostNet模型开发构建多商品细粒度图像识别系统

商品图像数据的细粒度识别有别于传统的图像识别任务&#xff0c;本身细粒度识别对于模型特征提取计算能力要求就比较高&#xff0c;在我们前面的一些项目中&#xff0c;涉及到的细粒度识别大多是同一物种下不同亚种的识别&#xff0c;比如&#xff1a;鸟类细粒度识别、狗类细粒…