前后端分离的跨域问题

article/2025/10/5 16:43:59

跨域问题原因

  在现在流行的前后端分离开发中,跨域问题突显了出来,跨域问题的根本原因:浏览器有同源策略限制,当前域名的js只能读取同域下的窗口属性,这是一个基础安全功能。那么什么是同源策略呢?即两资源的URL中 协议域名端口,都相同则称为同源,若两资源为不同源,则不允许共享资源。
例如:以http://www.baidu.com/dir1/a.html为例子

请求地址结果原因
http://www.baidu.com/dir1/b.html成功同一域名端口,相同文件夹
http://www.baidu.com/dir2/a.html成功同一域名端口,不同文件夹
https://www.baidu.com/dir1/b.html失败不同协议,http与https
http://www.baidu.com:8000/dir1/b.html失败不同端口,默认为80
http://www.sina.com/dir1/b.html失败不同域名
注: 核心判断方式为,端口及端口左边的地址要完全一致

CORS

  CORSCross-Origin Resource Sharing的缩写。也就是支持跨域资源共享,即不同域之间可以进行资源的相互访问。那么为什么要有CORS呢,其实很简单,浏览器的同源政策保证了安全的同时,也让我们不能访问其它域的资源,即使开发者认为的安全操作也不行,这时,我们就可以用一套协议来告诉浏览器,这某几个域在我们的服务范围之内,不要一棍打死。即有如下改变:
CORS出现之前:
  浏览器接收到服务器回复 --> 检查是否同源 --> 不同源就拒绝响应!/同源就响应!
CORS出现之后:
  浏览器接收到服务器回复 --> 检查一下response header --> 发现有特定字段Access-Control-Allow-Origin --> 检查这个header后面的值包不包含自己所在的域(打比方我们现在在www.baidu.com),浏览器检查发现后response header里面写的有Access-Control-Allow-Origin: https://www.baidu.com, https://www.google.com, 正好我们在允许的域里面! --> 浏览器响应服务器返回的数据(response)。

CORS 实现逻辑

  CORS需要浏览器和服务器也就是B/S两端分别实现!

浏览器要实现的内容:

  接收到服务器的回复之后检测回复头里面是否含有特定字段!有的话查看自己的域名是否在内,一定要这两个条件都符合!浏览器才会接受(或者说响应)服务器返回的回复!

服务器需要实现的内容:

  服务器需要在接受到浏览器发来的请求(request)后,在返回response之前!设置header,在header中里面包含特定字段,以便浏览器收到回复之后可以去检查,有字段证明服务器同意服务这个网站,浏览器就可以接受回复,没有字段或者字段的值不包含发送请求的网站,浏览器就不会响应回复内容!

注意:

  如果是复杂的跨域请求,浏览器则会先发送一个OPSTIONS探路,收到响应允许跨域后会再发送真实请求。
在这里插入图片描述
注:此时服务端写代码时,还需响应(OPTIONS)允许跨域。

跨域问题的解决方案

  • 修改浏览器的设置 (不推荐,不安全)
  • 修改请求的方式:jsonp (不推荐,诸多限制)
  • 用 Nignx 统一访问域
  • CORS 前端后端代码实现

CORS后端代码实现

  Nignx和前端的解决方案自行查找下吧,这里介绍下后端的常见解决方案

第一种方法:

在controller上加上@CrossOrigin 注解或者@CrossOrigin(origins = “http://localhost:8081”),优点是粒度更细,某URL是否跨域可以分开配置,缺点是,如果整个项目都要跨域,则每个controller都需要添加注解

@RestController
@RequestMapping(path = "/user")
@CrossOrigin  // 解决跨域问题
public class UserController {//......
}
第二种方法:

创建配置类CorsConfig,此方法统一配置,用的较多

@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS").allowCredentials(true).maxAge(3600).allowedHeaders("*");}
}
第三种方法:

创建一个过滤器CorsFilter

@WebFilter(filterName = "CorsFilter ")
@Configuration
public class CorsFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) res;response.setHeader("Access-Control-Allow-Origin","*");response.setHeader("Access-Control-Allow-Credentials", "true");response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");HttpServletRequest httpRequest = (HttpServletRequest) req;// OPTIONS method responseif (httpRequest.getMethod().equals("OPTIONS"))((HttpServletResponse) res).sendError(HttpServletResponse.SC_OK);chain.doFilter(req, res);}
}
第四种方法:

网关配置跨域(用于微服务)

@Configuration
public class CorsConfiguration {@Beanpublic CorsWebFilter corsWebFilter(){UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();//1、配置跨域corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");corsConfiguration.addAllowedOrigin("*");// 是否允许携带cookie跨域corsConfiguration.setAllowCredentials(true);source.registerCorsConfiguration("/**",corsConfiguration);return new CorsWebFilter(source);}
}

扩展阅读

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS


http://chatgpt.dhexx.cn/article/aJC0laD9.shtml

相关文章

前后端分离历史

文章目录 前后端分离前后端分离的历史前后端合并前后端耦合前后端“分离”大厂的方案前后端分离的理想方式前后端分离的好处前后端分离的挑战总结 前端历史前端开发的历史和趋势什么是前端前后端不分的时代后端 MVC 的开发模式前端工程师的角色典型的 PHP 模板AjaxWeb 2.0前端 …

小谈什么是前后端分离?

什么是前后端分离? 学习目标 什么是前后端分离?前后端分离初了解为什么要前后端分离?1、前后职责分离2、前后技术分离3、前后分离带来了用户用户体验和业务处理解耦4、前后分离,可以分别归约两端的设计 前后分离架构接口设计 用户…

java 前后端分离_Java项目如何实现前后端分离

Java项目如何实现前后端分离 发布时间:2020-11-20 15:55:52 来源:亿速云 阅读:103 作者:Leah 今天就跟大家聊聊有关Java项目如何实现前后端分离,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 构建springboot…

java 前后端分离

前后端分离的开发模式,这两年确实被炒得如火如荼,导致这个话题也成了面试极其爱问的一个问题,尤其是换工作、跳槽,之前不管你是做后端,还是前端,都可能会涉及。 面试官常问: 诶?你…

前后端ajax分离如何做seo,前后端分离 seo

目录 一、bootstrap 前后端分离 表现层完全由前端掌控是最好的。所以掌握jsp和jstl是挺好的,等你全掌握之后麻利得把页面模板搞定就可以嘲笑后端都是bottleneck了。 当然不愿意用jsp/jstl之类的,也可以考虑完全用ajax。 为什么说前后端分离不利于seo的原…

前后端分离

一、项目有前后端分离和前后端不分离: 在前后端不分离架构中,所有的静态资源和业务代码统一部署在同一台服务器上。服务器接收到浏览器的请求后,进行处理得到数据,然后将数据填充到静态页面中,最终返回给浏览器。 实现…

Spring Security 前后端分离

前后端分离概述 前后端分离指的就是前后端分离部署,前端 调用后端API,后端 返回 JSON格式数据,页面是由前端渲染并展示到浏览器中。 相比较传统的单体项目 ,页面是由后端渲染完成后返回给浏览器的。(jsp、thymeleaf、…

实现前后端分离

对目前的web来说,前后端分离已经变得越来越流行了,越来越多的企业/网站都开始往这个方向靠拢。那么,为什么要选择前后端分离呢?前后端分离对实际开发有什么好处呢? 为什么选择前后端分离 1. 在以前传统的网站开发中&#xff0c…

何为前后端分离?一文搞懂前后端分离发展史

目录 一、前言 二、前后端分离的演进过程 2.1 发展的三个阶段 2.2 前后端不分离阶段(Java的JSP作为前端视图时代) 2.3 前后端半分离阶段(前后端使用Ajax交互的半分离时代) 2.4 前后端完全分离阶段(前后端使…

前后端分离架构概述

1、背景 前后端分离已成为互联网项目开发的业界标准使用方式,通过nginxtomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户…

前后端分离架构,超全面详解~

此文通俗易懂,全面讲解前后端分离架构核心思想与作用,对学习微服务、开发企业项目大有裨益,建议收藏细品,好好领悟!~ 一、简介 前后端分离已成为互联网项目开发的业界标准使用方式,通过nginxtomcat的方式&a…

到底什么是前后端分离

1、到底什么是前后端分离? 前后端分离的"前"特指浏览器端(或客户端),直接呈现给用户的;后端是服务器端,处理业务逻辑和数据,不呈现给用户。 Java服务器端初学者最容易引起误解的一个概念就是:J…

c语言 链表基本操作

对于c语言的单链表来说,应该是数据结构中比较简单的一类结构,我们只要认识链表结构,对指针和结构体掌握好,其实编写代码并不算太难。 链表结构: 对于链表中的每一个结点,我们可以定义如下的结构体&#xf…

C语言——反转链表

大家好,本人第一次发布博客,目前正在学习数据结构,写博客的目的是一是想分享自己的学习过程,二也是每次写完代码后进行总结。希望大家一起共同学习! 现在我正在看《大话数据结构》这本书,每次学习过后我都会…

C语言数据结构之链表

前面的文章我们就一直说,学一个新东西之前一定要弄明白它的作用是什么,我们为什么要用它。之前讲C语言时我们讲到数组,数组的实质是一种顺序储存、随机访问、存储单元连续的线性表,既然存储单元连续,那么对其进行插入和…

C语言来实现链表创建

链表原理理解 链表作为一种线性数据,通过前后节点的指针指向,将所有数据串联起来。为了实现链表数据域的整体耦合,需要额外的指针域来标定前后数据的连接。通过下面的链表结构图,可以非常容易的理解链表的组成结构 头节点作为链表…

链表C语言和C++两种方式实现

一、C语言版本链表&#xff1a; 方向1&#xff1a;无表头 法一&#xff1a;尾插法 #include<stdio.h> #include<malloc.h> //打印 创建 释放 删除某个数 插入某个数 &#xff08;T_T&#xff09;5个功能 struct Node {int data;struct Node* next; }; typedef st…

C语言实现链表创建

C语言实现链表的创建 链表:是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点链表中每一个元素称为结点&#xff09;组成&#xff0c;结点可以在运行时动态生成。每个结点包括两个部分&#xf…

链表(c语言实现)

1.链表的分类 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; &#xff08;1&#xff09;单向或者双向 &#xff08;2&#xff09;带头或者不带头 &#xff08;3&#xff09;循环或者非循环 虽然有这么多的链表的结构&#xff0c;但是我们…

用c语言写链表

链表是数据结构的一种&#xff0c;是其他三个数据结构栈&#xff0c;树&#xff0c;图的基础&#xff0c;只有将链表这一数据结构弄懂&#xff0c;才能理解其他三种数据结构。 举一个例子&#xff0c;老师让你设计一个联系人系统&#xff0c;其中包括姓名&#xff0c;电话号&am…