IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> springmvc源码学习(三十三)请求出错时浏览器误报跨域问题 -> 正文阅读

[网络协议]springmvc源码学习(三十三)请求出错时浏览器误报跨域问题


前言

项目中定义了跨域过滤器,有些接口请求时出现错误,浏览器上却显示了跨域错误。

一、现象

Access to XMLHttpRequest at 'http://192.168.100.73:7901/demo/ftpFile/upload?project=1`1&projectVersion=11&relatedSoftware=CppUnit%E8%A2%AB%E6%B5%8B%E4%BB%B6&unit=11&type=document' from origin 'http://192.168.100.73:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
POST http://192.168.100.73:7901/demo/ftpFile/upload?project=1`1&projectVersion=11&relatedSoftware=CppUnit%E8%A2%AB%E6%B5%8B%E4%BB%B6&unit=11&type=document net::ERR_FAILED

二、跨域过滤器

public class CustomCorsFilter extends CorsFilter {
    private CorsProps corsProps;

    public CustomCrosFilter(CorsConfigurationSource configSource, CorsProps corsProps) {
        super(configSource);
        this.corsProps = corsProps;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {


        response.setHeader("Access-Control-Allow-Origin", corsProps.getOrigin());
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());
        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
        filterChain.doFilter(request, response);
    }

三、分析

1、通过调试,请求经过跨域过滤器时,响应头中设置了跨域的信息;

2、请求出现异常时,异常抛给了web容器,这里使用的容器是Undertow,在这里响应头被清理掉了;

					//重置 response
                    response.reset();                       //reset the response
                    exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
                    //清理了响应头
                    exchange.getResponseHeaders().clear();
                    //获取新的请求错误路径
                    String location = servletContext.getDeployment().getErrorPages().getErrorLocation(t);

3、在找到对应错误页面或默认错误页面后,没有再次通过跨域过滤器设置跨域信息,导致形响应结果中没有带跨域信息,引起浏览器报跨域的错。

四、解决方式

1、在错误页面中设置跨域信息

每个方法都调用一下设置跨域信息的方法

@RestController
public class ErrorPageController {

    @Autowired
    private CorsProps corsProps;

    @RequestMapping(value = "/400", produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity to400() {
        setCors();
        return new ResponseEntity(400, "请求有误");
    }

    @RequestMapping(value = "/404", produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity to404() {
        setCors();
        return new ResponseEntity(404, "找不到资源");
    }

    @RequestMapping(value = "/408", produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
    public ResponseEntity to408() {
        setCors();
        return new ResponseEntity(408, "请求超时");
    }

    @RequestMapping(value = "/500", produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity to500() {
        setCors();
        return new ResponseEntity(500, "服务器错误");
    }

    public void setCors() {
        HttpServletResponse response = SpringUtils.getResponse();
        String origin = SpringUtils.getRequest().getHeader("Origin");
        response.setHeader("Access-Control-Allow-Origin", origin);
        //服务器同意客户端发送cookies
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());

        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
    }
}

这样错误信息就变成了正常的信息:

POST http://192.168.100.73:7901/demo/ftpFile/unitSearch 400 (Bad Request)
Uncaught (in promise) {status: 400, message: "请求有误", desc: null, stackTrace: null, value: null,}

2、在切面中设置跨域信息

统一设置跨域信息

@Aspect
@Component
public class CorsAspect {

    @Autowired
    private CrosProps corsProps;

    /**
     * 让切面拦截到 ErrorPageController
     */
    @Pointcut("execution(* com.iscas.biz.config..error..*.*(..))")
    public void errorMethodPointcut() {
    }

    @Around(value = "errorMethodPointcut()")
    public Object around(final ProceedingJoinPoint joinPoint) throws Throwable {

        HttpServletResponse response = SpringUtils.getResponse();
        String origin = SpringUtils.getRequest().getHeader("Origin");
        response.setHeader("Access-Control-Allow-Origin", origin);
        //服务器同意客户端发送cookies
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());

        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());

        Object result = joinPoint.proceed();
        return result;
    }
}

3、在请求错误页面ErrorPageController时通过跨域过滤器

在跨域过滤器中重写 OncePerRequestFilter 的 shouldNotFilterErrorDispatch( )方法,让错误请求进入跨域过滤器设置跨域信息。

/**
     * 错误请求,是否不进入该过滤器
     * 默认为true,错误请求不会进入该过滤器,修改为false
     */
    protected boolean shouldNotFilterErrorDispatch() {
        return false;
    }
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-04 13:46:39  更:2022-01-04 13:49:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:52:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码