全网最全最详细的跨域解决方案

news2024/12/24 11:35:38

你们好,我是金金金。

在这里插入图片描述

前置知识

本篇文章以通俗易懂的方式进行描述,自己组织语言进行输出,尽量让每一个人都能看得懂。哪里有说的不正确的地方 大佬请在评论区指正!

  • 首先需要了解浏览器的同源策略

浏览器的同源策略

  • MDN解释地址:https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy

在这里插入图片描述

简单来说,同源策略是浏览器的一项重要安全机制,它限制了从一个来源加载的脚本如何与来自另一个来源的资源进行交互。其目的是防止不同来源之间的恶意行为,例如跨站脚本攻击(XSS)和跨站请求伪造(CSRF)

怎么算同源?

两个 URL协议域名端口 必须完全相同,才被认为是同源。否则,它们被认为是不同源的,那么就会发生跨域。如下

在这里插入图片描述

什么是跨域?

了解了浏览器的同源策略之后,想必你心中已经有答案了吧,两个 URL协议域名端口 有一个不同那么就会发生跨域,控制台报错如下

在这里插入图片描述

如何解决跨域?

  • 这里我分为前端后端分别讲解具体的解决方案。

前端

vite代理

  • 例如vitewebpack都有配置代理能解决跨域的一个方案。这里只讲解vite
  1. vite.config.ts配置文件:通过 server.proxy 选项来配置代理规则,我这里是ts项目,项目下一般都会有一个vite.config.ts,不是ts的项目那么就是.js文件,都差不多,配置如下:图中写明了各个参数意思

在这里插入图片描述

在这里插入图片描述

  1. 然后在你封装请求的文件当中使用这个/api 作为接口基准url即可

在这里插入图片描述

需要注意:Vite 的代理功能仅限于开发阶段,不会对生产环境产生任何影响。在生产环境中,你需要通过其他方式来处理跨域问题,比如在后端服务器上启用 CORS,或者在反向代理服务器(如 Nginx)上进行配置。

JSONP

原理

利用 <script> 标签的 src 属性没有跨域限制的特性来实现跨域数据访问

怎么做呢

事先定义一个用于获取跨域响应数据的回调函数,并通过没有同源策略限制的script标签发起一个请求(将回调函数的名称放到这个请求的query参数里),然后服务端返回这个回调函数的执行,并将需要响应的数据放到回调函数的参数里,前端的script标签请求到这个执行的回调函数后会立马执行,于是就拿到了执行的响应数据。

  • 参考代码如下:
function handleResponse(response) {
  //处理服务器返回的数据
}

var script = document.createElement('script');
script.src = 'https://jsonp.com/data?callback=handleResponse';
document.body.appendChild(script);

注意JSONP只支持GET请求,因为它依赖于<script>标签的跨域特性,而<script>标签不支持POST等其他HTTP方法

无需过多研究,了解即可,因为现在基本不会用到这种方式,感兴趣的小伙伴们自行百度~

选哪种?

如果你们项目开发阶段联调跨域,后端让前端解决的话 优先选择第一种:代理方式即可!

服务端

  • 这里以Java为例子

返回新的CorsFilter

@Configuration
public class GlobalCorsConfig {

  /**
   * 配置跨域过滤器
   * 允许特定条件下的跨域请求,以适应前端开发需求
   *
   * @return CorsFilter 配置好的跨域过滤器实例
   */
  @Bean
  public CorsFilter corsFilter() {
    // 创建一个新的CORS配置实例
    CorsConfiguration config = new CorsConfiguration();

    // 允许所有域名进行跨域调用
    config.addAllowedOrigin("*");
    // 允许跨越发送Cookie
    config.setAllowCredentials(true);
    // 允许所有头部信息进行跨域调用
    config.addAllowedHeader("*");
    // 允许所有请求方法进行跨域调用
    config.addAllowedMethod("*");

    // 创建一个URL基于CORS配置的源
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    // 将CORS配置应用到所有路径
    source.registerCorsConfiguration("/**", config);

    // 返回基于所配置的源创建的CORS过滤器实例
    return new CorsFilter(source);
  }
}

全局跨域

注意:需要确保Spring能扫描到这个配置类。

重写WebMvcConfigurer

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
 
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  //配置了所有的路由都可以跨域请求
                .allowedHeaders("*")  //配置了允许发送的自定义请求头
                .allowedMethods("*")  //配置了路径下所有的请求都可以跨域请求
                .allowedOriginPatterns("*")  //解决跨域资源共享(CORS)问题的一个配置项,用于允许来自任何来源的跨域请求
                .allowCredentials(true)  //指定在跨域请求中是否允许浏览器发送包含凭证信息的请求
                .maxAge(3600);  //指定在给定的时间范围内,是否允许浏览器缓存特定资源的请求结果。
    }
 
}

全局跨域

注意:需要确保Spring能扫描到这个配置类。

使用CrossOrigin注解

针对某个控制器方法配置跨域
@RestController public class MyController { 
    @CrossOrigin(origins = "http://example.com") // 允许来自指定域的跨域请求,"*"代表全部
    @GetMapping("/api/data") 
    public String getData() { 
        return "This is cross-origin data"; 
    } 
}
针对整个控制器配置跨域

@RestController
@CrossOrigin(origins = "*")
public class TestController {
    @RequestMapping("/test")
    public String test() {
        return "This is cross-origin data";
    }
}

局部跨域

无论是针对某个控制器方法还是针对整个控制器配置,都是属于局部配置,不建议使用,繁琐。

手动设置响应头


@RestController
public class TestController {
    @RequestMapping("/test")
    public HashMap<String, Object> test(HttpServletResponse response) {
        // 设置跨域
        response.setHeader("Access-Control-Allow-Origin", "*");
        return new HashMap<String, Object>() {{
            put("state", 200);
            put("data", "success");
            put("msg", "");
        }};
    }

局部跨域

纯手动添加响应头,不建议使用。繁琐。每个方法都得写

实现ResponseBodyAdvice

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
  /**
   * 内容是否需要重写(通过此方法可以选择性部分控制器和方法进行重写)
   *
   * @param methodParameter 方法参数,包含了方法的信息以及参数的信息
   * @param aClass          返回值的类型
   * @return 返回ture表示重写
   */
  @Override
  public boolean supports(MethodParameter methodParameter, Class aClass) {
    return true;
  }

  /**
   * 方法返回之前调用此方法
   *
   * @param o                  方法返回值
   * @param methodParameter    方法参数,包含了方法的信息以及参数的信息
   * @param mediaType          返回值的类型
   * @param aClass             返回值的类型
   * @param serverHttpRequest  请求
   * @param serverHttpResponse 响应
   * @return
   */
  @Override
  public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
    // 设置跨域
    serverHttpResponse.getHeaders().set("Access-Control-Allow-Origin", "*");
    return o;
  }
}

全局跨域

注意:需要确保Spring能扫描到这个配置类。

Nginx解决跨域

  • Nginx 服务器的配置文件中添加以下代码

在这里插入图片描述

server {
    listen       80;
    server_name  your_domain.com;
    location /api {
        # 允许跨域请求的域名,* 表示允许所有域名访问
        add_header 'Access-Control-Allow-Origin' '*';

        # 允许跨域请求的方法
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

        # 允许跨域请求的自定义 Header
        add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';

        # 允许跨域请求的 Credential
        add_header 'Access-Control-Allow-Credentials' 'true';

        # 预检请求的存活时间,即 Options 请求的响应缓存时间
        add_header 'Access-Control-Max-Age' 3600;

        # 处理预检请求
        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }
    # 其他配置...
}

server { listen 80; server_name your_domain.com; }

作用: 定义服务器监听的端口和域名。

解释: listen 80 表示服务器监听 80 端口,这是 HTTP 的默认端口。server_name your_domain.com 表示该服务器处理 your_domain.com 的请求。这里的 server 块是 Nginx 配置的基础结构,用于定义服务器如何处理特定域名的请求。

结语

耐心看完本篇文章,解决跨域就是简简单单轻轻松松

好啦,本篇文章到此结束,选择适合你们的一种解决方案吧~

  • 编写有误还请大佬指正,万分感谢。

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

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

相关文章

神经网络通俗理解学习笔记(3)注意力神经网络

Tansformer 什么是注意力机制注意力的计算键值对注意力和多头注意力自注意力机制注意力池化及代码实现Transformer模型Transformer代码实现 什么是注意力机制 注意力机制的发展史 Attention Mechanism Mnih V, Heess N, Graves A. Recurrent models of visual attention, 2014…

JVM 调优篇7 调优案例1-堆空间的优化解决

一 jvm优化 1.1 优化实施步骤* 1)减少使用全局变量和大对象&#xff1b; 2)调整新生代的大小到最合适&#xff1b; 3)设置老年代的大小为最合适&#xff1b; 4)选择合适的GC收集器&#xff1b; 1.2 关于GC优化原则 多数的Java应用不需要在服务器上进行GC优化&#xff1…

NeMo Curator 整理用于 LLM 参数高效微调的自定义数据集

目录 概述 预备知识 定义自定义文档构建器 下载数据集 解析和迭代数据集 将数据集写入 JSONL 格式 使用文档构建器加载数据集 使用现有工具统一 Unicode 格式 设计自定义数据集过滤器 编辑所有个人识别信息 添加指令提示 整合管线 概述 出于演示目的&#xff0c;本…

【PyQt6 应用程序】应用程序携带数据源文件一并打包

在开发好应用程序打包之后给到其他用户会发现数据文件比如封面图片不见了。 例如这样,很影响用户使用。 这里介绍一个非常简单的打包方法,不光要在打包命令的时候添加对应数据文件,在源码中也要进行一些简单的修改。 修改需要添加打包文件的地方。首先需要添加一个绝对路径…

143234234123432

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

【C++】c++的继承

目录 思维导图大纲&#xff1a; 1.基类和派生类 1.1 定义格式 1.2 继承方式 1.3 基类和派生类的转换 2. 继承中的作用域(隐藏关系) 2.1 考察继承作⽤域相关选择题 3. 派生类的默认成员函数 4. 继承类模板 5. 一个不能被继承的类 ​编辑 6.继承与友元 ​编辑 7. 继…

Java面向对象六大设计原则总结(超级详细,附有代码、图解以及案例)

文章目录 三.软件(面向对象)设计原则3.1 开闭原则(OSP)3.1.1 概述3.1.2 案列 3.2 里氏代换原则(LSP)3.2.1 概述3.2.2 案例 3.3 依赖倒转原则(DIP)3.3.1概述3.3.2 案例 3.4 接口隔离原则(ISP)3.4.1 概述3.4.2 案列 3.5 迪米特法则(DP)3.5.1 概述3.5.2 案例 3.6 合成复用原则(CRP…

红黑树前语

目录 概念 性质 红黑树与AVL树的比较 过两天更新红黑树的模拟实现,中秋快乐各位 概念 1. 概念&#xff1a; 是一种搜索二叉树&#xff0c; 但在每个结点上增加一个存储位表示节点的颜色&#xff0c;可以是Red 或 Black。通过对任何一条从根到叶子的路径上各个节点着色方式的…

[JVM]JVM内存划分, 类加载过程, 双亲委派模型,垃圾回收机制

文章目录 一. JVM内存划分1. 堆2. 栈3. 元数据区4. 程序计数器 二. 类加载过程1. 加载2. 验证3. 准备4. 解析5. 初始化 三. 双亲委派模型四. JVM的垃圾回收机制GC1. 找到需要回收的对象2. 释放垃圾的策略 一. JVM内存划分 JVM就是java进程 这个进程一旦跑起来, 就会从操作系统…

Windows本地制作java证书(与jeecgboot配置本地证书ssl问题)

1&#xff1a;JDK生成自签证书SSL,首先以管理员身份运行CMD窗口&#xff0c;执行命令 keytool -genkey -alias testhttps -keyalg RSA -keysize 2048 -validity 36500 -keystore "F:/ssl/testhttps.keystore"F:\ssl>keytool -genkey -alias testhttps -keyalg R…

PCIe进阶之TL:Memory, I/O, and Configuration Request Rules TPH Rules

1 Memory, I/O, and Configuration Request Rules 下述规则适用于 Memory 请求、IO 请求和配置请求。 除了公共的 header 字段外,所有 Memory 请求、IO 请求和配置请求还包括以下字段: (1)Requester ID[15:0] 和 Tag[9:0],组成了 Transaction ID 。 (2)Last DW BE[3:0]…

计算架构模式之接口高可用

接口高可用整体框架 接口高可用主要应对两类问题&#xff1a;雪崩效应和链式效应。 雪崩&#xff1a;当请求量超过系统处理能力之后&#xff0c;会导致系统性能螺旋快速下降&#xff0c;本来系统可以处理1000条&#xff0c;但是当请求量超过1200的时候&#xff0c;此时性能会下…

【415】【最高乘法得分】

目录 使用dp python版本 java版本 递推式 python版本 java版本 PS: java语法 1.定义数组 2.记忆化 3.计算max 难绷&#xff0c;本来想着4个指针&#xff0c;和四数之和那道题挺类似的。。。。 四数之和好像剪枝和预处理都是先排序的比较好做。 无奈&#xff0c;只…

[网络]https的概念及加密过程

文章目录 一. HTTPS二. https加密过程 一. HTTPS https本质上就是http的基础上增加了一个加密层, 抛开加密之后, 剩下的就是个http是一样的 s > SSL HTTPS HTTP SSL 这个过程, 涉及到密码学的几个核心概念 明文 要传输的真正意思是啥 2)密文 加密之后得到的数据 这个密文…

CTF(misc)1和0的故事

题目链接 下载题目后是一堆整齐的01字符串&#xff0c;猜测是生成二维码&#xff0c;将0变成白色方块&#xff0c;1变成黑色方块。 0000000001110010000000000 0000000000011110100000000 0000000001110001000000000 0000000010111100000000000 0000000010101010000000000 00…

Python基础语法(3)下

列表和元组 列表是什么&#xff0c;元组是什么 编程中&#xff0c;经常需要使用变量&#xff0c;来保存/表示数据。变量就是内存空间&#xff0c;用来表示或者存储数据。 如果代码中需要表示的数据个数比较少&#xff0c;我们直接创建多个变量即可。 num1 10 num2 20 num3…

ModuleNotFoundError: No module named ‘datasets‘

报错信息&#xff1a; 解决&#xff1a;安装datasets 方法1: pip install datasets 方法2: python3可以使用以下命令&#xff1a; pip3 install datasets

【智路】智路OS Perception Fusion Service

Perception Fusion Service https://gitee.com/ZhiluCommunity/airos-edge/raw/r2.0/docs/02_Service/Perception_Fusion_Service.md 多传感器融合感知模块的主要任务是接收各传感器感知的障碍物信息&#xff0c;融合这些障碍物信息&#xff0c;得到融合后的障碍物信息。 智…

Tuxera NTFS for Mac 2023绿色版

​ 在数字化时代&#xff0c;数据的存储和传输变得至关重要。Mac用户经常需要在Windows NTFS格式的移动硬盘上进行读写操作&#xff0c;然而&#xff0c;由于MacOS系统默认不支持NTFS的写操作&#xff0c;这就需要我们寻找一款高效的读写软件。Tuxera NTFS for Mac 2023便是其中…

接口自动化框架入门(requests+pytest)

一、接口自动化概述 二、数据库概述 2.1 概念 存储数据的仓库&#xff0c;程序中数据的载体 2.2 分类 关系型数据库&#xff1a;安全 如mysql&#xff0c;oracle&#xff0c;SQLLite database tables 行列 非关系型数据库&#xff1a;高效 如redis&#xff0c;mongoDB 数…