解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域

解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域

    • Tomcat 配置允许跨域
    • Web 项目配置允许跨域
    • Tomcat 同时允许静态文件和 Web 服务跨域

偶尔遇到一个 Tomcat 部署项目跨域问题,因为已经处理过太多跨域了,觉得很简单 。

结果尝试多次均不能达到想要的结果,又经过 Nginx、Tomcat 以及项目配置才完全搞定。

另外,之前总结了篇 Web 项目跨域问题(Geoserver),也可以综合参考。

本文包含 Tomcat 配置允许跨域、Web 项目配置允许跨域以及同时允许跨域三部分。


Tomcat 配置允许跨域

使用 Tomcat 作为静态文件服务还是比较简单和常用的,而跨域问题也比较容易解决。

Tomcat 静态文件允许跨域,设置比较简单,百度一搜一堆,这里简单贴一下。

1.Tomcat web.xml 配置允许所有跨域

设置之后,所有静态文件以及服务均被允许跨域。

(1) 当未配置允许跨域时,报跨域错误

在这里插入图片描述

浏览器直接访问是正常的:

在这里插入图片描述

(2)Tomcat conf/web.xml 文件配置允许跨域

在这里插入图片描述


<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>

</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

配置之后,重启 Tomcat,再次访问则正常:

在这里插入图片描述


Web 项目配置允许跨域

Web 项目,这里指的是 java 项目,打包的时候基本是选择 war 包或者 jar 包。

老项目以 war 包居多,新项目(Springboot)以 jar 包居多。

war 可以直接在 Tomcat 中部署启动,而 jar 包则往往通过命令启动。

因此,war 的跨域相关配置会收到 Tomcat 跨域配置影响。jar 包独立启动,不会受 Tomcat 影响。

这里介绍一下 Web 项目各种允许跨域配置。

1. 未配置允许跨域时,报跨域错误

在这里插入图片描述

而浏览器地址栏直接可以正常访问:

在这里插入图片描述

2. 配置允许跨域

(1)自定义过滤器允许跨域

WEB-INF/web.xml 配置文件允许所有接口跨域,一般不建议这样配置。


<filter>
  <filter-name>cors</filter-name>
  <filter-class>MyCORSFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>cors</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
  

过滤类,任意目录即可,以根目录为例,其他目录需要加上包路径:


import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class MyCORSFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException, IOException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String origin = (String) servletRequest.getRemoteHost()+":"+servletRequest.getRemotePort();
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
        response.setHeader("Access-Control-Allow-Credentials","true");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

(2)继承 WebMvcConfigurationSupport 允许跨域

Springboot 框架下的配置,允许所有接口跨域,Springboot 环境下测试生效,Spring MVC环境下测试未生效。


package com.mapsharp.map.web.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.Charset;
import java.util.List;

/**
 * @author
 * @Description: 设置允许跨域访问static资源
 * @date 2019/6/39:26
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        System.out.println("自动配置生效addResourceHandlers");
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }

    //前端跨域
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")//设置允许跨域的路径
                .allowedOrigins("*")//设置允许跨域请求的域名
                .allowedHeaders("*")//是否允许证书 不再默认开启
                .exposedHeaders("Access-Control-Allow-Origin,Access-Control-Allow-Credentials")//是否允许证书 不再默认开启
                .allowCredentials(true)//是否允许证书 不再默认开启
                .allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE")//设置允许的方法
                .maxAge(3600);//跨域允许时间
    }

    //为了解决中文编码方式乱码问题
    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        converter.setWriteAcceptCharset(false);
        return converter;
    }

    @Bean
    public ObjectMapper getObjectMapper() {
        return new ObjectMapper();
    }

    @Bean
    public MappingJackson2HttpMessageConverter messageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(getObjectMapper());
        return converter;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(responseBodyConverter());
        converters.add(messageConverter());
    }
}

(3)@CrossOrigin 注解允许跨域

注意 Spring 框架版本,测试项目 Spring MVC 和 SpringBoot 均生效。

根据实际需求,选择在 类或者方法 剩添加 @CrossOrigin 注解即可。

这样的好处是,最小颗粒度控制允许跨域。

在这里插入图片描述

在这里插入图片描述


Tomcat 同时允许静态文件和 Web 服务跨域

Tomcat 静态文件和 Web 服务同时允许跨域,即 Tomcat webapp 目录下同时存在静态文件服务和 war 包启动的服务。

开始阶段发现,配置 Web 服务允许跨域之后不生效。但是静态文件可以正常访问。

后来经过测试,要想静态文件和 Web 服务接口都允许跨域,需要以下条件:

1.Tomcat 设置允许所有跨域,开放最大权限

注意下图中红框部分,笔者当时没注意,导致一直没解决问题。

注意:红框部分需要注释掉!

在这里插入图片描述

2.Web 服务不设置任何允许跨域配置(@CrossOrigin注解不影响)

Tomcat 中的 Web 服务,即 war 包中,不能设置允许跨域配置。

但是经过测试 @CrossOrigin注解 可以设置,不影响跨域结果。

在这里插入图片描述


文章小结:如果 Tomcat 和 Web 服务都配置了 web.xml 允许跨域,则会出现冲突,不能解决跨域问题。

在这里插入图片描述

如果只是 Web 项目,则在接口层面进行控制;

如果也需要静态文件和 Web 服务同时允许跨域,则在Tomcat 中进行一次配置即可。

同时配置允许跨域不生效的原因:个人感觉是因为有啥冲突,AI 的回答是:

在这里插入图片描述
在这里插入图片描述


参考博客:

tomcat 设置允许跨域访问

Tomcat解决跨域问题(Access-Control-Allow-Origin,403,404)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

企业微信hook接口协议,ipad协议http,外部联系人图片视频文件下载

外部联系人文件下载 参数名必选类型说明file_id是StringCDNkeyopenim_cdn_authkey是String认证keyaes_key是Stringaes_keysize是int文件大小 请求示例 {"url": "https://imunion.weixin.qq.com/cgi-bin/mmae-bin/tpdownloadmedia?paramv1_e80c6c6c0cxxxx3544d9…

设计模式-状态模式在Java中的使用示例-信用卡业务系统

场景 在软件系统中&#xff0c;有些对象也像水一样具有多种状态&#xff0c;这些状态在某些情况下能够相互转换&#xff0c;而且对象在不同的状态下也将具有不同的行为。 为了更好地对这些具有多种状态的对象进行设计&#xff0c;我们可以使用一种被称之为状态模式的设计模式…

【Android】android 10 jar_sdk_library添加

前言 当前项目遇到客户&#xff0c;Android 10 平台&#xff0c;需要封装jar_sdk_library给第三方应用使用。其中jar_sdk_library中存在aidl文件。遇到无法编译通过问题。 解决 system/tools/aidl修改 Android.bp修改

vue中web端播放rtsp视频流(摄像头监控视频)(海康威视录像机)

一、ffmpeg安装​​​​​​ ffmpeg下载 https://ffmpeg.org/download.html找ffmpeg-release-essentials.zip点击下载&#xff0c;下载完解压ffmpeg.exe 程序运行 二、配置ffmpeg环境变量 添加成功后验证是否生效任意地方打开cmd窗口输入 ffmpeg 打印如下表示成功 三、node…

Ribbon负载均衡器

1. 负载均衡器 目前主流的负载方案分为以下两种&#xff1a;&#xff08;面试题&#xff09; 1.1 服务端负载均衡 在消费者和服务提供方中间使用独立的代理方式进行负载&#xff0c;有硬件的&#xff08;比如 F5&#xff09;&#xff0c;也有软件的&#xff08;比如 Nginx&a…

【重磅开源】MapleBoot项目开发规范

基于SpringBootVue3开发的轻量级快速开发脚手架 &#x1f341;项目简介 一个通用的前、后端项目模板 一个快速开发管理系统的项目 一个可以生成SpringBootVue代码的项目 一个持续迭代的开源项目 一个程序员的心血合集 度过严寒&#xff0c;终有春日&#xff…

uniapp配置了pages.json 的 tabbar 国际化,小程序切换语言没有实时切换

如上图&#xff0c;按照uniapp官方文档配置了tabbar的国际化 但是微信小程序实时切换语言没有实时刷新 解决方案&#xff1a; 在App.vue中加入以下代码&#xff1a; 在onLaunch中执行方法即可

LLM大语言模型(十二):关于ChatGLM3-6B不兼容Langchain 的Function Call

背景 基于本地的ChatGLM3-6B直接开发LangChain Function Call应用&#xff0c;发现其输出的action和action_input非常不稳定。 表现为生成的JSON格式回答非常容易出现不规范的情况&#xff0c;导致LangChain的Agent执行报错&#xff0c;或者进入死循环。 ChatGLM3-6B不兼容La…

SQLAlchemy的使用

SQLAlchemy中filter函数的使用 https://blog.csdn.net/m0_67093160/article/details/133318889 创建临时字段 select id , CONCAT(‘内容’) AS fullname from example_table;

设计模式之外观模式

1、详细介绍 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它为子系统的一组接口提供了一个统一的入口点&#xff08;外观类&#xff09;。外观模式简化了客户端与子系统之间的交互&#xff0c;屏蔽了子系统内部的复杂性&#xff0c;使客户…

【Unity】UnityEvent(一)

​UnityEvent----高效管理游戏事件的利器 在游戏开发中&#xff0c;事件系统是实现各种功能的关键组成部分。它允许我们将不同对象之间的交互解耦&#xff0c;使得代码更加模块化和易于维护。而UnityEvent作为Unity引擎提供的一种强大的事件系统工具&#xff0c;为开发者提供了…

c++ - 模板(一)

文章目录 一、函数模板 一、函数模板 1、概念 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函数的特定 类型版本。 2、原理 函数模板是一个蓝图&#xff0c;它本身并不是函数&#xff0c;是编译器用…

宜搜科技死磕港交所上市:从搜索引擎到广告投放,业绩疲态凸显

近日&#xff0c;宜搜科技控股有限公司&#xff08;下称“宜搜科技”&#xff09;向港交所递交招股书&#xff0c;计划在香港主板上市&#xff0c;中银国际为其独家保荐人。 值得注意的是&#xff0c;宜搜科技已在资本市场辗转多年。该公司曾于2014年向纽交所递交上市申请&…

Web3与传统互联网:挑战、融合与共生

引言 Web3技术正以惊人的速度改变着我们的互联网体验。作为一个基于区块链的去中心化互联网模型&#xff0c;Web3不仅带来了创新和变革&#xff0c;还引发了与传统互联网之间的对比和讨论。本文将深入探讨Web3与传统互联网之间的关系&#xff0c;挑战&#xff0c;以及可能的融…

智慧火电厂合集 | 数字孪生助推能源革命

火电厂在发电领域中扮演着举足轻重的角色。主要通过燃烧如煤、石油或天然气等化石燃料来产生电力。尽管随着可再生能源技术的进步导致其比重有所减少&#xff0c;但直至 2023 年&#xff0c;火电依然是全球主要的电力来源之一。 通过图扑软件自主研发 HT for Web 产品&#xf…

模块三:二分——162.寻找峰值

文章目录 题目描述算法原理解法一&#xff1a;暴力查找解法二&#xff1a;二分查找 代码实现解法一&#xff1a;暴力查找解法二&#xff1a;CJava 题目描述 题目链接&#xff1a;162.寻找峰值 根据题意&#xff0c;需要使用O(log N)的时间复杂度来解决&#xff0c;得出本道题…

对浅拷贝的理解

问题背景 我之前一直以为浅拷贝出来的新对象和旧对象的引用地址是相同的&#xff0c;但是通过Object和发现浅拷贝的新对象和旧对象的引用地址不同&#xff01;&#xff01; const obj1 { name: "Alice", test: { age: 12 } };const obj4 Object.assign({}, obj1);…

linux中 虚拟机 修改时间 centos7

方法1 &#xff1a;虚拟机内 设置 方法2 代码实现 timedatectl set-timezone "Asia/Shanghai"

iOS 17上如何恢复数据?iOS 17 数据恢复软件

“您好&#xff0c;我正在为我的 iPhone 寻找一款iOS 17 数据恢复软件。升级到 iOS 17 后&#xff0c;我丢失了 iPhone 上的所有照片、联系人和消息。有什么建议吗&#xff1f;” ——丹尼 iOS 17数据恢复软件下载 升级到iOS 17后如何恢复丢失的数据&#xff1f;由于在 iPhone…

Django中的事务

1 开启全局的事务 DATABASES {default: {ENGINE: django.db.backends.mysql, # 使用mysql数据库NAME: tracerbackend, # 要连接的数据库USER: root, # 链接数据库的用于名PASSWORD: 123456, # 链接数据库的用于名HOST: 192.168.1.200, # mysql服务监听的ipPORT: 3306, …