SpringCloud微服务Zuul跨域问题
目前项目结构是VUE做前端,后端采用微服务架构,在开发时前端需要跨域请求数据,通过ZuulFilter配置解决了简单跨域请求需要。但当需要在请求的header中增加token信息时,出现了请求失败的情况,浏览器和后台均出现OPTIONS类型请求相关提示。

G69H9U%UT6~`8Q1J.png)
Failed to load http://192.168.1.149:8000/server/addressbook/delete: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values 'http://192.168.1.242:5500, http://192.168.1.242:5500', but only one is allowed. Origin 'http://192.168.1.242:5500' is therefore not allowed access.
这里其实已经很明确了,说头包含多个值,只允许一个然后我们看请求信息

为什么会这样呢?其实是我们在使用ZuulFilter的时候获取的 RequestContext 他给我们自带了 Access-Control-Allow-Origin,Access-Control-Allow-Credentials 这两个参数,所以我们在程序里面就不需要加了
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zuul.mgzuul.util.JwtHelperUtil;
import com.zuul.mgzuul.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* @Author 唐银
* @Description //TODO
* @Date 2018-01-03 14:20
* @ClassName MyFilter
* @ClassNotes
**/
@Slf4j
@Component
public class MyFilter extends ZuulFilter { @Resource
private RedisUtil redisUtil; @Autowired
private JwtHelperUtil jwtHelperUtil; @Override
public String filterType() {
/*
pre:可以在请求被路由之前调用
route:在路由请求时候被调用
post:在route和error过滤器之后被调用
error:处理请求时发生错误时被调用
* */
// 前置过滤器
return FilterConstants.PRE_TYPE; } @Override
public int filterOrder() { //// 优先级为0,数字越大,优先级越低
return 0;
} @Override
public boolean shouldFilter() {
// RequestContext ctx = RequestContext.getCurrentContext();
// HttpServletRequest request = ctx.getRequest();
// //过滤各种POST请求
// if(request.getMethod().equals(RequestMethod.OPTIONS.name())){
// return true;
// }
return true; } @Override
public Object run() { System.out.println("*****************PostFilter run start*****************");
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletResponse response = ctx.getResponse();
HttpServletRequest request = ctx.getRequest();
//response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin")); //这里注释掉
//response.setHeader("Access-Control-Allow-Credentials","true"); //这里注释掉
response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host,Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,Authorization,Token,accessToken");
response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers");
String accessToken = request.getHeader("accessToken");
//跨域请求放行
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
System.out.println("*****************PostFilter run end*****************");
return null;
} String url = request.getRequestURI();
if(url.indexOf("/login")!=-1){
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
System.out.println("*****************PostFilter run end*****************");
return null;
} //验证token
//String accessToken = request.getHeader("accessToken");
/*String accessToken = request.getParameter("accessToken");
if(StringUtils.isBlank(accessToken)){
log.debug("accessToken 不存在!");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);// 返回错误码
ctx.setResponseBody("{\"result\":\"token不存在\"}");// 返回错误内容
ctx.set("isSuccess", false);
return null;
}
Object token_ob = redisUtil.get(accessToken);
if(token_ob == null){
log.debug("accessToken 已经过期");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);// 返回错误码
ctx.setResponseBody("{\"result\":\"token过期\"}");// 返回错误内容
ctx.set("isSuccess", false);
return null;
}else {
Claims claims = jwtHelperUtil.parseJWT(accessToken);
if(claims == null){
log.debug("accessToken 错误");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);// 返回错误码
ctx.setResponseBody("{\"result\":\"token错误\"}");// 返回错误内容
ctx.set("isSuccess", false);
return null;
}
}
//通过后更新登陆过期时间
redisUtil.set(accessToken,accessToken, 259200);*/
//允许继续路由
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
System.out.println("*****************PostFilter run end*****************");
return null;
}
}
注释掉以后ok 就成功解决了 (注意在zuul做了跨域设置就不需要在各个服务再做了不然也是会出现这个问题的)
QQ群:216868740
SpringCloud微服务Zuul跨域问题的更多相关文章
- SpringCloud微服务之跨服务调用后端接口
SpringCloud微服务系列博客: SpringCloud微服务之快速搭建EurekaServer:https://blog.csdn.net/egg1996911/article/details ...
- 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul
通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...
- springcloud微服务实战:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin
相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...
- springcloud微服务实战:Eureka+Zuul+Ribbon+Hystrix+SpringConfig
原文地址:http://blog.csdn.net/yp090416/article/details/78017552 springcloud微服务实战:Eureka+Zuul+Ribbon+Hyst ...
- SpringCloud微服务(基于Eureka+Feign+Hystrix+Zuul)
一.搭建注册中心 1.1.创建一个cloud-service项目 1.2:POM文件依赖 1 <?xml version="1.0" encoding="UTF-8 ...
- 【微服务】之七:轻松搞定SpringCloud微服务-API权限控制
权限控制,是一个系统当中必须的重要功能.张三只能访问输入张三的特定功能,李四不能访问属于赵六的特定菜单.这就要求对整个体系做一个完善的权限控制体系.该体系应该具备针区分用户.权限.角色等各种必须的功能 ...
- springcloud微服务架构搭建
SpringCloud微服务框架搭建 一.微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通 ...
- SpringCloud微服务基础学习
看了蚂蚁课堂的微服务学习,确实学习了不少关于微服务的知识,现在总结学习如下 : SpringCloud微服务基础单点系统架构传统项目架构传统项目分为三层架构,将业务逻辑层.数据库访问层.控制层放入在一 ...
- java~springcloud微服务目录索引
回到占占推荐博客索引 最近写了不过关于java,spring,微服务的相关文章,今天把它整理一下,方便大家学习与参考. java~springcloud微服务~目录索引 springcloud~服务注 ...
随机推荐
- Fork/Jion框架详解
◆Fork/Jion框架可以干什么◆ 如果你要处理1万条数据,但是你的能力暂时还不够,一个简单快捷的办法就是你可以把每次只处理100条,等到处理100次之后再把所有的结果聚合起来你就处理完了这1万条数 ...
- SpringBoot2.0 项目异常日志,但不影响运行(待解决)
第一种: 2019-04-17 01:46:33 [INFO] [org.apache.juli.logging.DirectJDKLog:175] - Error parsing HTTP requ ...
- pandas 对数据帧DataFrame中数据的索引及切片操作
1.创建数据帧 index是行索引,即每一行的名字:columns是列索引,即每一列的名字.建立数据帧时行索引和列索引都需要以列表的形式传入. import pandas as pd df = pd. ...
- PLC
https://www.cnblogs.com/dathlin/p/7469679.html C#读写三菱PLC和西门子PLC数据 使用TCP/IP 协议https://blog.csdn.net/x ...
- Python后台开发Django(启动)
Django版本为:2.1.7 Python的web框架,MTV思想 MVC Model(模板文件,数据库操作) view(视图模板文件 )controller(业务处理) MTV Model(模 ...
- mysql数据库打开连接时报错:1251
考试之前由于一直在做团队项目导致疏忽了数据库 等到今天来连接做考试的时候发现报错:1251 网上的解释以及解决方法: 今天下了个 MySQL8.0,发现Navicat连接不上,总是报错1251: 原因 ...
- 从壹开始前后端分离 [.netCore 填坑 ] 三十三║ ⅖ 种方法实现完美跨域
缘起 哈喽大家周四好,趁着大家在团建的时候花一个下午学点儿东西,也是督促大家学习哟,希望大家看到老张的文章,可以有一丢丢的学习动力.不过话说过来,该吃的团建还是要去的,不能学我呀 [ /(ㄒoㄒ)/~ ...
- 【Caffe篇】--Caffe solver层从初始到应用
一.前述 solve主要是定义求解过程,超参数的 二.具体 #往往loss function是非凸的,没有解析解,我们需要通过优化方法来求解. #caffe提供了六种优化算法来求解最优参数,在solv ...
- pip安装python库时使用国内镜像资源加速下载过程
pip默认安装包是从网站https://pypi.org/simple下载,我们可以将其改成国内的镜像网站,加速下载过程,下面以安装numpy库为例: pip install -i https://p ...
- Dubbo简介
1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...