No 'Access-Control-Allow-Origin' header: 跨域问题踩坑记录
前言
前两周在服务器上部署一个系统时,遇到了跨域问题,这也不是第一次遇到跨域问题了,本来以为解决起来会很顺利,没想到解决过程中遇到了很多坑,所以觉得有必要写一篇博客记录一下这个坑。
问题产生原因
本来我们组的应用都有一个统一的网关服务进行接口请求转发,相关的配置都做好了,并不存在跨域问题。但前两周因为业务拓展,需要将部分应用拆分出来,部署到其他服务器上,这里面就包含我负责的两个应用。
其中一个应用,因为是前后端不分离的项目,不存在跨域问题,所以部署起来比较顺利,直接打了一个jar包丢到服务器上面就顺利跑起来了。另一个项目则是前后端分离的项目,打jar包部署的过程倒时挺顺利的,可是当我把前端用nginx跑起来之后,却看到了类似下图这样一堆报错:
这一看就是跨域问题了。
解决过程
1、修改nginx配置(不起作用)
因为上一次遇到跨域问题,我就是通过nginx配置代理转发解决的,所以这次我首先想到的还是通过修改nginx配置来解决这个问题,所以我在nginx配置文件中添加了类似这样的配置:
server{
listen 8888;
server_name 192.168.1.100; location /{
proxy_pass http://192.168.1.100:8080;
} location /api{
proxy_pass http://192.168.1.100:8081; // 以api开头的接口请求,全部转发到这里
}
}
然而,并不起作用。之后,我又在nginx配置文件中添加了一些关于请求头的设置,如下所示:
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,HEAD,PUT';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true'
同样的,也没有解决问题。到这里,我暂时放弃通过修改nginx配置文件来解决跨域问题的想法了。
2、在后端代码中添加跨域处理配置
关于如何在后端解决跨域问题,我之前也了解过,查了一下网上资料后,在代码中添加了一下两个配置类:
WebMvcConfig:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /**
* 全局处理接口跨域
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
// .allowedOrigins("*")
// 这里网上的资料大部分说的是.allowedOrigins("*"),但因为我的springboot版本是2.5.5,
// allowCredentials为true时并且allowedOrigins不为空且为ALL(这个ALL就是*)时就会抛出异常
// 所以这里我设置的是.allowedOriginPatterns("*")
.allowedOriginPatterns("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
}
}
CORSFilter:
import org.springframework.stereotype.Component; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; /**
* 全局处理接口跨域
*/
@Component
public class CORSFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.setHeader("Access-Control-Allow-Headers", "*");
chain.doFilter(request, response);
} @Override
public void destroy() {
Filter.super.destroy();
} }
本来以为加上了这两个配置类,这把绝对没问题了,可惜,问题依然没有解决。
但这次部署上去之后,报错信息发生了变化,提示某些请求头(如client_id)没能成功跨域,这也给了我一些启发。
3、最终的解决方案
最后的最后,我将CORSFilter配置类中的:
res.setHeader("Access-Control-Allow-Headers", "*");
修改为:
res.setHeader("Access-Control-Allow-Headers", "client_id, Authorization, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
然后,打包部署上去,总算解决了跨域问题。
总结
这次问题解决后,我又查了一些资料,发现了以下两个知识点:
1、Access-Control-Allow-Origin 请求头的设置是有一些特殊限制的,当 Access-Control-Allow-Credentials 的值为 true 时会导致Access-Control-Allow-Origin 无法被设置为「*」。
2、因为我的springboot版本较新,所以网上通用的很多跨域配置对我不太适用。比如 Access-Control-Allow-Headers 不能直接设置为 *,而需要将特定的请求头给明确列出来才可生效。
这次折腾了这么久,尝试了网上各种方法都不生效,主要就是因为以上两点,好在最后总算顺利解决了。
No 'Access-Control-Allow-Origin' header: 跨域问题踩坑记录的更多相关文章
- Access control allow origin 简单请求和复杂请求
原文地址:http://blog.csdn.net/wangjun5159/article/details/49096445 错误信息: XMLHttpRequest cannot load http ...
- 记一次header跨域与cookie共享
最近把左边的传统模式,换成了右边通过js直接调api拿数据并渲染,于是变出现了ajax的跨域问题:XMLHttpRequest cannot load http://api.abc.com/?s ...
- vue cli+axios踩坑记录+拦截器使用,代理跨域proxy(更新)
16319 1.首先axios不支持vue.use()方式声明使用,看了所有近乎相同的axios文档都没有提到这一点建议方式 在main.js中如下声明使用 import axios from 'ax ...
- vue cli+axios踩坑记录+拦截器使用,代理跨域proxy
1.首先axios不支持vue.use()方式声明使用,看了所有近乎相同的axios文档都没有提到这一点 建议方式 在main.js中如下声明使用 import axios from 'axios'; ...
- axios踩坑记录+拦截器使用+vue cli代理跨域proxy+webpack打包部署到服务器
1.小小的提一下vue cli脚手架前端调后端数据接口时候的本地代理跨域问题,如我在本地localhost访问接口http://40.00.100.100:3002/是要跨域的,相当于浏览器设置了一道 ...
- SpringBoot2.x整合Shiro出现cors跨域问题(踩坑记录)
1. Springboot如何跨域? 最简单的方法是: 定义一个配置CorsConfig类即可(是不是简单且无耦合到令人发指) @Configuration public class CorsConf ...
- 解决js ajax跨越请求 Access control allow origin 异常
// 解决跨越请求的问题 response.setHeader("Access-Control-Allow-Origin", "*");
- access-Control-Allow-Origin跨域请求安全隐患
最新的W3C标准里是这么实现HTTP跨域请求的,Cross-Origin Resource Sharing,就是跨域的目标服务器要返回一系列的Headers,通过这些Headers来控制是否同意跨域. ...
- cookie跨域那些事儿
一个请求从发出到返回,需要浏览器和服务端的协调配合.浏览器要把自己的请求参数带给服务端,服务端校验参数之后,除了返回数据,也可能会顺便把请求是否缓存,cookie等信息告诉浏览器.当请求是跨域请求的时 ...
随机推荐
- PAT (Basic Level) Practice (中文)1007 素数对猜想 (20分)
1007 素数对猜想 (20分) 让我们定义dn为:dn = pn+1 − pn,其中pi是第i个素数.显然有d1 = 1,且对于n > 1有dn是偶数."素数对猜想"认 ...
- UltraSoft - Beta - 测试报告
UltraSoft - Beta - 测试报告 在测试过程中发现了多少Bug?有哪些是Beta阶段的新Bug?有哪些是Alpha阶段没有发现的Bug? 很多Bug在开发阶段就已经经过测试了,我们在Be ...
- 第4次 Beta Scrum Meeting
本次会议为Beta阶段第4次Scrum Meeting会议 会议概要 会议时间:2021年6月4日 会议地点:「腾讯会议」线上进行 会议时长:0.5小时 会议内容简介:对完成工作进行阶段性汇报:对下一 ...
- netty传输java bean对象
在上一篇博客(netty入门实现简单的echo程序)中,我们知道了如何使用netty发送一个简单的消息,但是这远远是不够的.在这篇博客中,我们来使用netty发送一个java bean对象的消息,但是 ...
- mongodb的聚合操作
在mongodb中有时候我们需要对数据进行分析操作,比如一些统计操作,这个时候简单的查询操作(find)就搞不定这些需求,因此就需要使用 聚合框架(aggregation) 来完成.在mongodb ...
- Noip模拟15 2021.7.14
T1 夜莺与玫瑰 题目越发的变态起来... 这题刚开始看超级像仪仗队,好不容易码完欧拉函数后尝试×2后输出但不对!! 于是选择了跳过.... 正解居然是莫比乌斯函数....我也是醉了 预处理完就剩下$ ...
- 盘点 GitHub 年度盛会|附视频
「Universe 2021」是 GitHub 于今年举办的开发者盛会,本次 Universe 2021 大会采用线上直播模式,为期两天已于上周落下帷幕. 这是 GitHub 举办的一年一度开发者盛会 ...
- JDK源码阅读(5):HashTable类阅读笔记
HashTable public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, ...
- shiro550反序列化分析
拖了很久的shiro分析 漏洞概述 Apache Shiro <= 1.2.4 版本中,加密的用户信息序列化后存储在Cookie的rememberMe字段中,攻击者可以使用Shiro的AES加密 ...
- 什么是齐博x1标签
X系列的标签跟V系列的标签区别还是很大的.在V系列的时候,只有一种很简单的标签比如$label[XXXX]以前的标签相对现在的来说太简单的点,所以在功能上也比较受限.X系列目前有几下几种标签 {qb: ...