博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringCloud(4)——Web工程、SpringCloud微服务前后端分离接口跨域问题解决方案...
阅读量:5358 次
发布时间:2019-06-15

本文共 7812 字,大约阅读时间需要 26 分钟。

目前互联网市场流行,前端后端分离开发模式:前端(表现层)--中间层(Http请求接口+Json数据交互)--后端(业务逻辑层)

但是这种模式会引出一种新的问题:前后端交互跨域请求问题

究竟是什么事跨域,请看下面讲解:

JavaScript处于安全方面的考虑,不允许跨域调用其他页面的对象。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。

简单来说就是因为JavaScript同源策略的限制,比如a.com域名下的js无法操作b.com或者a.b.com域名下的对象,更简单来说就是:不同域名下的url请求不允许通信。

解决方案如下:

1、普通web工程

  1.1 引入对应jar包

com.thetransactioncompany
cors-filter
1.7
com.thetransactioncompany
java-property-utils
1.9

  1.2 web.xml配置

CORS
com.thetransactioncompany.cors.CORSFilter
cors.allowOrigin
*
cors.supportedMethods
GET, POST, HEAD, PUT, DELETE
cors.supportedHeaders
Accept, Origin, X-Requested-With, Content-Type, Last-Modified
cors.exposedHeaders
Set-Cookie
cors.supportsCredentials
true
CORS
/*

2、Spring Cloud微服务架构跨域问题解决

  2.1 引入对应jar依赖

com.thetransactioncompany
cors-filter
1.7
com.thetransactioncompany
java-property-utils
1.9

  2.2 添加接口请求CorsFilter过滤

package com.sinosoft.config;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import org.springframework.web.filter.CorsFilter;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configurationpublic class WebMvcConfigurer extends WebMvcConfigurerAdapter {    private static final Logger LOGGER = LoggerFactory.getLogger(WebMvcConfigurer.class);    /**     * 添加拦截器 目的是拦截前端过来的请求     *     * @param registry     */    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new RequestLog()).addPathPatterns("/imove/**");        super.addInterceptors(registry);    }    /**     * 解决前端跨域请求     * 

* 简单跨域就是GET,HEAD和POST请求,但是POST请求的"Content-Type"只能是application/x-www-form-urlencoded, multipart/form-data 或 text/plain *

* 反之,就是非简单跨域,此跨域有一个预检机制,说直白点,就是会发两次请求,一次OPTIONS请求,一次真正的请求 * * @return */ @Bean public CorsFilter corsFilter() { LOGGER.info("开启CorsFilter,解决前后端分离模式接口交互跨域问题"); final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); final CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true);// 允许cookies跨域 corsConfiguration.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin corsConfiguration.addAllowedHeader("*");// #允许访问的头信息,*表示全部 corsConfiguration.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了 corsConfiguration.addAllowedMethod("*");//允许所有的请求方式 urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); return new CorsFilter(urlBasedCorsConfigurationSource); }}

3、SpringCloud 定义AOP切面来监控接口请求

package com.sinosoft.config;import com.sinosoft.domain.Deviceinfo;import com.sinosoft.dto.DeviceinfoDTO;import com.sinosoft.dto.common.IMReqeustEntity;import com.sinosoft.dto.common.RequestInfo;import com.sinosoft.repository.DeviceinfoRepository;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;/** * Created by zh on 03/29/17. */@Aspect   //定义一个切面@Configurationpublic class LogRecordAspect {    /**     * 日志打印     */    private static final Logger LOGGER = LoggerFactory.getLogger(LogRecordAspect.class);    @Autowired    private DeviceinfoRepository deviceinfoRepository;    /**     * 定义切点Pointcut     * 监控请求对应controller过来接口     */    @Pointcut("execution(* com.sinosoft.controller.*Controller.*(..))")    public void excudeService() {    }    @Around("excudeService()")    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {        LOGGER.info("监控前端请求management应用模块过来的接口...");        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();        String url = request.getRequestURL().toString();//获取接口请求详细路径        String method = request.getMethod();            //获取接口请求方法        String uri = request.getRequestURI();           //获取接口请求路径        String queryString = request.getQueryString();  //获取接口请求参数        Object[] args = pjp.getArgs();        System.out.println("请求参数:" + args[0].toString());        try {            for (int i = 0; i < args.length; i++) {                if (args[i] instanceof RequestInfo
) { RequestInfo
r = (RequestInfo
) args[i]; //开始进行入参解密处理 //开始进行设备信息保存 IMReqeustEntity entity = r.getImReqeustEntity(); saveDeviceInfo(convertDeviceInfoDTO(entity)); LOGGER.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, r.toString()); } else { LOGGER.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, args[i]); } } } catch (Exception e) { LOGGER.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString); } // result的值就是被拦截方法的返回值 Object result = pjp.proceed(); LOGGER.info("请求结束,Controller的返回值是 " + result); return result; } /** * 将请求设备参数信息转换为设备对象 * * @param entity E * @return T */ private DeviceinfoDTO convertDeviceInfoDTO(IMReqeustEntity entity) { try { DeviceinfoDTO deviceinfoDTO = new DeviceinfoDTO(); deviceinfoDTO.setCity("河南省"); return deviceinfoDTO; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 前端请求的入参信息转换为设备对象 * * @param entity e * @return T */ private Deviceinfo saveDeviceInfo(DeviceinfoDTO entity) { try {// Deviceinfo deviceinfo = deviceinfoRepository.// save(EntityAndDTO.convert(entity, Deviceinfo.class));// return deviceinfo; } catch (Exception e) { e.printStackTrace(); LOGGER.error("保存设备信息异常,原因:" + e.getMessage()); } return null; }}

 

转载于:https://www.cnblogs.com/xushuyi/articles/6681709.html

你可能感兴趣的文章
python中的网页标签等字符处理
查看>>
Mybatis输入类型和结果类型
查看>>
Linux常用命令(五)
查看>>
Linux常用命令(四)
查看>>
Linux常用命令(六)
查看>>
Linux常用命令(六)
查看>>
Linux常用命令(八)
查看>>
Linux常用命令(七)
查看>>
Linux常用命令(九)
查看>>
Linux常用命令(十一)
查看>>
Linux常用命令(十)
查看>>
实验吧之这就是一个坑
查看>>
Linux常用命令(十二)
查看>>
Linux常用命令(十三)
查看>>
Linux常用命令(十五)
查看>>
Linux常用命令(十四)
查看>>
Linux常用命令(十七)
查看>>
Linux常用命令(十六)
查看>>
Linux常用命令(二十四)
查看>>
4种java定时器
查看>>