Java 解决跨域问题

JAVA | Java 解决跨域问题


文章目录

  • JAVA | Java 解决跨域问题
  • 引言
    • 什么是跨域(CORS)
    • 什么情况会跨域
  • 解决方案
    • 前端解决方案
    • 后端解决方案
  • 具体方式
    • 一、使用Filter方式进行设置
    • 二、继承 HandlerInterceptorAdapter
    • 三、实现 WebMvcConfigurer
    • 四、使用Nginx配置
    • 五、使用 `@CrossOrgin` 注解
  • Spring Cloud Gateway 跨域配置


引言

我们在开发过程中经常会遇到前后端分离而导致的跨域问题,导致无法获取返回结果。跨域就像分离前端和后端的一道鸿沟,君在这边,她在那边,两两不能往来.

什么是跨域(CORS)

跨域(CORS)是指不同域名之间相互访问。跨域,指的是浏览器不能执行其他网站的脚本,它是由浏览器的同源策略所造成的,是浏览器对于JavaScript所定义的安全限制策略。

什么情况会跨域

  • 同一协议, 如http或https
  • 同一IP地址, 如127.0.0.1
  • 同一端口, 如8080

以上三个条件中有一个条件不同就会产生跨域问题。

解决方案

前端解决方案

  1. 使用JSONP方式实现跨域调用;
  2. 使用NodeJS服务器做为服务代理,前端发起请求到NodeJS服务器, NodeJS服务器代理转发请求到后端服务器;

后端解决方案

  • nginx反向代理解决跨域
  • 服务端设置Response Header(响应头部)的Access-Control-Allow-Origin
  • 在需要跨域访问的类和方法中设置允许跨域访问(如Spring中使用@CrossOrigin注解);
  • 继承使用Spring Web的CorsFilter(适用于Spring MVC、Spring Boot)
  • 实现WebMvcConfigurer接口(适用于Spring Boot)

具体方式

一、使用Filter方式进行设置

使用Filter过滤器来过滤服务请求,向请求端设置Response Header(响应头部)的Access-Control-Allow-Origin属性声明允许跨域访问。

@WebFilter
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-Methods", "*");  response.setHeader("Access-Control-Max-Age", "3600");  response.setHeader("Access-Control-Allow-Headers", "*");response.setHeader("Access-Control-Allow-Credentials", "true");chain.doFilter(req, res);  }  
}

二、继承 HandlerInterceptorAdapter

@Component
public class CrossInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "*");response.setHeader("Access-Control-Allow-Credentials", "true");return true;}
}

三、实现 WebMvcConfigurer

@Configuration
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
public class AppConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")  // 拦截所有的请求.allowedOrigins("http://www.abc.com")  // 可跨域的域名,可以为 *.allowCredentials(true).allowedMethods("*")   // 允许跨域的方法,可以单独配置.allowedHeaders("*");  // 允许跨域的请求头,可以单独配置}
}

四、使用Nginx配置

location / {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Headers X-Requested-With;add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;if ($request_method = 'OPTIONS') {return 204;}
}

五、使用 @CrossOrgin 注解

如果只是想部分接口跨域,且不想使用配置来管理的话,可以使用这种方式

在Controller使用

@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/{id}")public User get(@PathVariable Long id) {}@DeleteMapping("/{id}")public void remove(@PathVariable Long id) {}
}

在具体接口上使用

@RestController
@RequestMapping("/user")
public class UserController {@CrossOrigin@GetMapping("/{id}")public User get(@PathVariable Long id) {}@DeleteMapping("/{id}")public void remove(@PathVariable Long id) {}
}

Spring Cloud Gateway 跨域配置

spring: cloud:gateway:globalcors:cors-configurations:'[/**]':# 允许跨域的源(网站域名/ip),设置*为全部# 允许跨域请求里的head字段,设置*为全部# 允许跨域的method, 默认为GET和OPTIONS,设置*为全部allow-credentials: trueallowed-origins:- "http://xb.abc.com"- "http://sf.xx.com"allowed-headers: "*"allowed-methods:- OPTIONS- GET- POST- DELETE- PUT- PATCHmax-age: 3600

注意: 通过gateway 转发的其他项目,不要进行配置跨域配置

有时即使配置了也不会起作用,这时你可以根据浏览器控制的错误输出来查看问题,如果提示是 response 中 header 出现了重复的 Access-Control-* 请求头,可以进行如下操作

import java.util.ArrayList;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Component("corsResponseHeaderFilter")
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {@Overridepublic int getOrder() {// 指定此过滤器位于NettyWriteResponseFilter之后// 即待处理完响应体后接着处理响应头return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {return chain.filter(exchange).then(Mono.defer(() -> {exchange.getResponse().getHeaders().entrySet().stream().filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1)).filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS)|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS)|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_MAX_AGE))).forEach(kv -> {kv.setValue(new ArrayList<String>() {{add(kv.getValue().get(0));}});});return chain.filter(exchange);}));}
}

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

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

相关文章

c语言写天气预报程序,微信小程序实现天气预报功能

获取应用实例var app getApp()Page({data: {//加载状态loadingHidden: false,//当前温度currentTemperature: ,//夜间温度nightAirTemperature: ,//白天温度dayAirTemperature: ,//当前天气weather: ,//污染指数aqi: ,//污染程度quality: ,//风力windPower: ,//风向windDirect…

Spring 异常处理三种方式

Spring 异常处理三种方式 异常处理方式一. ExceptionHandler异常处理方式二. 实现HandlerExceptionResolver接口异常处理方式三. ControllerAdviceExceptionHandler三种方式比较说明(强烈推荐各位看一下&#xff0c;我觉得自己总结的比较多&#xff0c;嘿嘿&#xff0c;不对之…

Netty常见面试题 与 答案

Netty基础知识 什么是Netty&#xff1f; Netty 是一款用于高效开发网络应用的 NIO 网络框架&#xff0c;它大大简化了网络应用的开发过程&#xff1b; 封装了JDK底层的NIO模型&#xff0c;提供高度可用的API&#xff0c;用于快速开发高性能服务端和客户端&#xff1b;精心设计…

c语言’内存清除函数,c语言常用内存处理函数

memset()#includevoid*memset(void*s,int c,size_t n);功能&#xff1a;将s的内存区域的前n个字节以参数c填入(用来初始化)参数&#xff1a;s:需要操作内存s的首地址c:填充的字符&#xff0c;c虽然参数为int,但必须是unsigned char,范围为0-255n:指定需要设置的大小返回值&…

c语言编俄罗斯方块有注释,C语言学习1年-俄罗斯方块(无注释)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include #include #include int randtmp3,i,j,p,q,fx,fy,s,t,c,r,dltm,begin0,fq,k,a,sj,score0;int dla32000;int nx[5],ny[5],h[5],m[25];int x[8][4]{0,0,0,0,0,-2,-1,0,0,0,1,2,0,0,0,0,0,-1,0,1,0,0,1,1,0…

使用 @ControllerAdvice 和 实现ResponseBodyAdvice接口, 拦截Controller方法默认返回参数,统一处理返回值/响应体

使用 ControllerAdvice 和 实现ResponseBodyAdvice接口&#xff0c; 拦截Controller方法默认返回参数&#xff0c;统一处理返回值/响应体 1、Controller代码 以下是Controller方法源码&#xff1a; RestController RequestMapping("/manage/user") public class Te…

c语言中字符占用的存储单元,C语言知识点第1章.doc

C语言知识点第1章C语言知识点总结(二) 第八节 字符字符常量定义&#xff1a;一对单引号括起来的一个字符。如‘A’、‘a’、‘9’相应字符对应的ASCII编码值(见附录四)字符常量占用一个字节的存储单元(一个字节占8位)重点&#xff1a;表 C语言中常见的转义字符字符形式意义字符…

Spring的@ExceptionHandler注解使用方法

文章目录1&#xff0c;基本使用方法2&#xff0c;注解的参数3&#xff0c;就近原则4&#xff0c;注解方法的返回值5&#xff0c;错误的操作1&#xff0c;基本使用方法 Spring的ExceptionHandler可以用来统一处理方法抛出的异常&#xff0c;比如这样&#xff1a; ExceptionHan…

c语言dfs算法全排列代码,c语言dfs解决全排列问题

如1,2,3三个元素的全排列为&#xff1a;1,2,31,3,22,1,32,3,13,1,23,2,1共3*2*16种代码简单实现n个元素的全排列#include #define N 5int a[100];//存放数字序列int mark[100];//判断数字是否使用过,mark[3]1表示3这个数字能用int count;void dfs(int i,int a[N]);int main(int…

CAS单点登录详细流程

一、CAS简介和整体流程 CAS 是 Yale 大学发起的一个开源项目&#xff0c;旨在为 Web 应用系统提供一种可靠的单点登录方法&#xff0c;CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点&#xff1a; 【1】开源的企业级单点登录解决方案。 【2】CAS Server 为…

android 图片自动拉伸,解决关于ImageView自适应的问题(拉伸变形,图片模糊)

今天接手一个项目发现有个地方的图片显示非常小&#xff0c;而且还不够清晰&#xff0c;也没办法自适应屏幕的显示&#xff0c;非常的影响美观&#xff0c;于是 就像这优化一下。先看看优化前的效果和优化后的效果。修复后修复前布局文件修复前&#xff1a;修复前布局文件修复后…

redisTemplate.opsForValue()中方法讲解

查看源码可以看到redisTemplate.opsForValue()中的方法都定义在ValueOperations<K, V> 中&#xff0c;该接口中一共有17个方法&#xff1a; public interface ValueOperations<K, V> {void set(K key, V value);void set(K key, V value, long timeout, TimeUnit …

android获取未知字符串,android – 未知的URL内容:// downloads / my_dow...

我正在使用Download Manger下载一些多媒体文件并对其进行分类.我也在使用Crashlytics,这是一个错误,我经常在不同的设备和Android版本上得到它.我正在寻找你的解决方案/建议&#xff01;java.lang.IllegalArgumentException: Unknown URL content://downloads/my_downloadsat a…

spring boot配置dubbo(properties)

spring boot与dubbo配置(properties) dubbo和zookeeper配合使用&#xff0c;具体的它们之间的配置这里不说了。 一、spring boot与dubbo配置有两种方式&#xff1a; 1&#xff09;spring boot在自己的配置文件application.properties 配置dubbo。&#xff08;本篇主要说这个&…

spring boot配置dubbo(XML)

上一篇写的是spring boot在自己的properties配置文件中简单配置dubbo的步骤&#xff0c;那种配置有很多的功能&#xff08;比如超时时间、是否检查&#xff09;等等&#xff0c;配置起来也挺麻烦的&#xff0c;而我们也习惯传统的那种XML形式的dubbo配置。 这一篇写的是spring…

android线程优先级大小,android 设置线程优先级 两种方式

1) android.os.Process.setThreadPriority (int priority)或android.os.Process.setThreadPriority (int tid&#xff0c; int priority)priority&#xff1a;【-20&#xff0c; 19】&#xff0c;高优先级 -> 低优先级.(2)java.lang.Thread.setPriority (int priority)prior…

spring boot配置dubbo注意事项

spring boot配置dubbo注意事项 通过前两篇文章&#xff0c;知道了spring boot配置dubbo有两种方式。具体请回顾前两篇文章吧。 现在主要是说下spring boot在自己的application.properties 文件里配置dubbo内容&#xff0c;这种方式遇到的问题。 问题一&#xff1a;dubbo接口…

spring boot配置mybatis和事务管理

spring boot配置mybatis和事务管理 一、spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下&#xff1a; <!-- Spring Boot 启动父依赖 --> <parent><groupId>org.springframework.boot</groupId><artifactId>spr…

android hud sdk,Android HUD SDK | 百度地图API SDK

简介为了给用户提供更安全优质的服务&#xff0c;LBS开放平台针对Android平台的SDK产品引入Key认证机制&#xff0c;用户在使用之前需要先申请配置Key&#xff0c;并在程序相应位置填写您的Key。Key机制&#xff1a;每个Key仅且唯一对于1个应用验证有效&#xff0c;即对该Key配…

spring boot配置druid(德鲁伊)

spring boot配置druid(德鲁伊) 关于druid的介绍请看 阿里巴巴温少访谈 1.引入相关依赖&#xff0c;全部依赖是上一篇spring bootmybatis依赖的基础上&#xff0c;再加上下边的依赖&#xff0c;如下&#xff1a; <!-- Druid数据库连接池组件 --> <dependency><…