SPRING BOOT跨域访问处理

Posted 今天付出是为明天回报

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPRING BOOT跨域访问处理相关的知识,希望对你有一定的参考价值。

尊重原创:http://blog.csdn.net/ruiguang21/article/details/77878933

 

  1. 问题场景:由于项目中使用到跨域访问,今天也得到高人指点,所以写出来分享给大家可能是考虑到前后端分离,前端后端服务器不在一台机器上,出现这种跨域访问的情况。正常情况下本地访问是没有问题,但是遇到这种非同一台服务器的情况下,就会报错Access-Control-Allow-Origin。具体报错内容不记得了。
  2. 问题解决方案一:采用添加拦截器的方式对请求添加跨域访问的头,允许跨域访问。
  3. 包com.meicloud.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.log4j.Logger;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    
    公共 类 CommonInterceptor 扩展HandlerInterceptorAdapter {
    
        私人 最终 静态   记录器记录器= Logger.getLogger(CommonInterceptor。类);
        
        @覆盖
        公共 布尔 preHandle(HttpServletRequest请求,HttpServletResponse响应,对象处理程序)抛出异常{
            logger.info( “添加跨域访问头配置,Access-Control-Allow-Origin:*” );
            // 跨域访问CORS 
            response.addHeader(“Access-Control-Allow-Origin”,“*” );
            response.addHeader( “Access-Control-Allow-Methods”,“POST,GET,OPTIONS,PUT,DELETE,HEAD” );
            response.addHeader( “Access-Control-Allow-Headers”,“S_ID,content-type” );
            response.addHeader( “Access-Control-Max-Age”,“3600000” );
            response.addHeader( “Access-Control-Allow-Credentials”,“true” );
            
            // 让请求,不被缓存, 
            response.setHeader(“Cache-Control”,“no-cache” );  
            response.setHeader( “Cache-Control”,“no-store” );  
            response.setHeader( “Pragma”,“no-cache” );  
            response.setDateHeader( “Expires”,0 );
            logger.debug 
            ( “================================== preHandle” );
            返回 true ;
        }
        
        @覆盖
        公共 无效postHandle(HttpServletRequest请求,
                HttpServletResponse响应,对象处理程序,
                ModelAndView modelAndView)抛出Exception {logger.debug 
            ( “================================== postHandle” );
        }
        
        
        @覆盖
        public  void afterCompletion(HttpServletRequest request,
                HttpServletResponse响应,对象处理程序,Exception ex)
                抛出Exception {
            logger.debug( “================================== afterCompletion” );
        }
    }
    

      

  4. 上面是拦截器内容,下面是对拦截器的配置。
包com.meicloud.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.meicloud.interceptor.CommonInterceptor;

@ComponentScan
@组态
公共 类 WebMvcConfig 扩展WebMvcConfigurerAdapter {
    
    @覆盖
    public  void addInterceptors(InterceptorRegistry registry){
         // TODO自动生成的方法存根 
        registry.addInterceptor(new CommonInterceptor())。addPathPatterns(“/ getDOC” );
    }
  
}

  然后就可以在控制器中使用他了,下面是我的控制器

 

我们可以通过调用
这个方法来实现一个简单的方法来实现这个方法,这个方法可以
用来实现一个简单的方法来实现这个方法
。
BaseReturn baseReturn = new BaseReturn(); 

字符串名称= mailEntity.getName(); 
String company = mailEntity.getCompany(); 
字符串部门= mailEntity.getDepartments(); 
String job = mailEntity.getJob(); 
String email = mailEntity.getEmail(); 
String phone = mailEntity.getPhone(); 
String doc = mailEntity.getDoc(); 

尝试{ 
if(name == null || name.equals(“”)){ 
throw new CommenException(“姓名不能为空!
} 
if(email == null || email.equals(“”)){ 
throw new CommenException(“Email不能为空!”); 
} 
if(phone == null || phone.equals(“”)){ 
throw new CommenException(“电话号码不能为空!”); 
} 
if(doc == null || doc.equals(“”)){ 
throw new CommenException(“文档不能为空!”); 
} 
}赶上(例外E1){ 
baseReturn.setCode(ReturnType.FAIL); 
baseReturn.setMsg(e1.getMessage()); 
log.error(e1.getMessage()); 
返回基地返回; 
} 

try { 
// iMailClent.sendMail(mailEntity); 
iMailClent.sendhtmlMail(mailEntity); 
baseReturn.setCode(ReturnType.SUCCESS); 
catch(Exception e){ 
e.printStackTrace();
baseReturn.setCode(ReturnType.FAIL); 
baseReturn.setMsg( “发送邮件失败!”); 
log.error(e.getMessage()); 
} 

return baseReturn; 
}

  接下来是前端的调用,前端采用ajax post请求

 

 

var params = {
                          名称:名称,
                          公司:公司,
                          部门:部门,
                          工作:工作,
                          电子邮件:电子邮件,
                          电话:电话,
                          doc: ‘/ doc/ api.doc‘
                  };


var type =‘POST‘ ;
var url = Config.host + url;


$就({
        url:url,
        数据:JSON.stringify(params),
        键入:type,
        contentType: “application / json” ,
        async:false ,
        成功:函数(数据){
             // TODO成功
        },
        错误:函数(数据){
             // TODO失败
        }
    });

问题解决方案二:使用JSONP来实现跨域访问,直接上代码,前端代码为:

url =‘http:// localhost:9999 / getDOC‘+‘?name =‘+ params.name 
             +‘&company =‘+ params.company
             +‘&departments =‘+ params.departments +‘&job =‘+ params.job
             +‘&email =‘+ params.email +‘&phone =‘+ params.phone +‘&doc =‘
            + params.doc;

$就({
        url:url,
        键入: ‘get‘ ,
        async:false ,
        dataType: “jsonp” ,
        jsonpCallback: “回调” ,
        成功:功能(数据){
            // TODO成功
        },
        错误:函数(数据){
            // TODO失败
        }
    });

  限制调用方式为get,数据类型为jsonp。后端也必须响应JSONPObject对象。

@ResponseBody
    @RequestMapping(value =“/ getDOC”,method = RequestMethod.GET)
    公共JSONPObject getDOC(HttpServletRequest请求,字符串回调){
        
        BaseReturn baseReturn = new BaseReturn();
        
        String name = request.getParameter(“name” );
        String company = request.getParameter(“company” );
        String departments = request.getParameter(“departments” );
        String job = request.getParameter(“job” );
        String email = request.getParameter(“email” );
        String phone = request.getParameter(“phone” );
        String doc = request.getParameter(“doc” );
        
        尝试{
             if(name == null || name.equals(“” )){
                 throw  new CommenException(“姓名不能为空!” );
            }
            if(email == null || email.equals(“” )){
                 throw  new CommenException(“Email不能为空!” );
            }
            if(phone == null || phone.equals(“” )){
                 throw  new CommenException(“电话号码不能为空!” );
            }
            if(doc == null || doc.equals(“” )){
                 throw  new CommenException(“文档不能为空!” );
            }
        } 捕获(例外E1){
            baseReturn.setCode(ReturnType.FAIL);
            baseReturn.setMsg(e1.getMessage());
            log.error(e1.getMessage());
            返回 新的JSONPObject(callback,baseReturn);
        }
        
        MailEntity mailEntity = new MailEntity();
        mailEntity.setCompany(公司);
        mailEntity.setDepartments(部门);
        mailEntity.setDoc(DOC);
        mailEntity.setEmail(电子邮件);
        mailEntity.setJob(工作);
        mailEntity.setName(名称);
        mailEntity.setPhone(电话);
        
        
        尝试{
             iMailClent.sendHtmlMail(mailEntity);
            baseReturn.setCode(ReturnType.SUCCESS);
        } 捕获(例外五){
            e.printStackTrace();
            baseReturn.setCode(ReturnType.FAIL);
            baseReturn.setMsg( “发送邮件失败!” );
            log.error(e.getMessage());
        }
        
        返回 新的JSONPObject(callback,baseReturn);
    }
    

  今天得到高人指点,原来有一种更加简便的方法,可以实现。不过原理肯定都是一样的,通过给请求添加消息头来设置跨域访问,这点是无疑的。新的解决办法就是给控制器或方法添加@CrossOrigin注解,具体详情请参考:http://spring.io/blog/2015/06/08/cors-support-in-spring-framework

@ResponseBody
    @RequestMapping(value =“/ getDOC”,method = RequestMethod.POST)公共BaseReturn getDOC(@RequestBody MailEntity mailEntity,HttpServletRequest请求,HttpServletResponse响应,HttpSession httpSession){ 
    @CrossOrigin // 使用注解方式添加跨域访问消息头
    
        log.info( “执行控制器HomeController.getDOC”);

  

以上是关于SPRING BOOT跨域访问处理的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 登录重定向外部地址,出现跨域问题 怎么办?

Spring Boot 最简单的解决跨域问题

Spring Boot 最简单的解决跨域问题

从Spring-Boot开始深入理解Spring系列——Spring-Boot处理web开发的跨域问题

Spring Boot 2中对于CORS跨域访问的快速支持

spring boot跨域请求访问配置以及spring security中配置失效的原理解析