博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring boot 跨域访问处理
阅读量:5255 次
发布时间:2019-06-14

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

  1. 问题场景:由于项目中使用到跨域访问,今天也得到高人指点,所以写出来分享给大家。可能是考虑到前后端分离,前端后端服务器不在一台机器上,出现这种跨域访问的情况。正常情况下本地访问是没有问题,但是遇到这种非同一台服务器的情况下,就会报错 Access-Control-Allow-Origin 。具体报错内容不记得了。
  2. 问题解决方案一:采用添加拦截器的方式对请求添加跨域访问的头,允许跨域访问。
    package 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;public class CommonInterceptor extends HandlerInterceptorAdapter  {    private final static  Logger logger = Logger.getLogger(CommonInterceptor.class);        @Override    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {        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");        return true;    }        @Override    public void postHandle(HttpServletRequest request,            HttpServletResponse response, Object handler,            ModelAndView modelAndView) throws Exception {        logger.debug("==================================postHandle");    }            @Override    public void afterCompletion(HttpServletRequest request,            HttpServletResponse response, Object handler, Exception ex)            throws Exception {        logger.debug("==================================afterCompletion");    }}

    上面是拦截器内容,下面是对拦截器的配置。

    package 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@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {        @Override    public void addInterceptors(InterceptorRegistry registry) {        // TODO Auto-generated method stub        registry.addInterceptor(new CommonInterceptor()).addPathPatterns("/getDOC");    }  }

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

    @ResponseBody

    @RequestMapping(value="/getDOC",method=RequestMethod.POST)
    public BaseReturn getDOC(@RequestBody MailEntity mailEntity, HttpServletRequest request, HttpServletResponse response, HttpSession httpSession){
    log.info("excute controllor HomeController.getDOC");
    BaseReturn baseReturn = new BaseReturn();
    String name = mailEntity.getName();
    String company = mailEntity.getCompany();
    String departments = mailEntity.getDepartments();
    String job = mailEntity.getJob();
    String email = mailEntity.getEmail();
    String phone = mailEntity.getPhone();
    String doc = mailEntity.getDoc();
    try {
    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("文档不能为空!");
    }
    } catch (Exception e1) {
    baseReturn.setCode(ReturnType.FAIL);
    baseReturn.setMsg(e1.getMessage());
    log.error(e1.getMessage());
    return baseReturn;
    }
    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 = {                          name:name,                          company:company,                          departments:departments,                          job:job,                          email:email,                          phone:phone,                          doc:'/doc/api.doc'                  };var type = 'POST';var url = Config.host + url;$.ajax({        url : url,        data : JSON.stringify(params),        type : type,        contentType : "application/json",        async : false,        success : function(data) {            //TODO 成功        },        error : function(data) {            //TODO 失败        }    });

     

  3. 问题解决方案二:使用 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;$.ajax({        url : url,        type : 'get',        async : false,        dataType : "jsonp",        jsonpCallback : "callback",        success : function(data) {            //TODO 成功        },        error : function(data) {            //TODO 失败        }    });

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

    @ResponseBody    @RequestMapping(value="/getDOC",method=RequestMethod.GET)    public JSONPObject getDOC(HttpServletRequest request,String callback){                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");                try {            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("文档不能为空!");            }        } catch (Exception e1) {            baseReturn.setCode(ReturnType.FAIL);            baseReturn.setMsg(e1.getMessage());            log.error(e1.getMessage());            return new JSONPObject(callback, baseReturn);        }                MailEntity mailEntity = new MailEntity();        mailEntity.setCompany(company);        mailEntity.setDepartments(departments);        mailEntity.setDoc(doc);        mailEntity.setEmail(email);        mailEntity.setJob(job);        mailEntity.setName(name);        mailEntity.setPhone(phone);                        try {             iMailClent.sendHtmlMail(mailEntity);            baseReturn.setCode(ReturnType.SUCCESS);        } catch (Exception e) {            e.printStackTrace();            baseReturn.setCode(ReturnType.FAIL);            baseReturn.setMsg("发送邮件失败!");            log.error(e.getMessage());        }                return new JSONPObject(callback, baseReturn);    }

     

  4. 今天得到高人指点,原来有一种更加简便的方法,可以实现。不过原理肯定都是一样的,通过给请求添加消息头来设置跨域访问,这点是无疑的。新的解决办法就是给controller或方法添加 @CrossOrigin 注解,具体详情请参考:http://spring.io/blog/2015/06/08/cors-support-in-spring-framework
    @ResponseBody    @RequestMapping(value="/getDOC",method=RequestMethod.POST)    @CrossOrigin //使用注解方式添加跨域访问消息头    public BaseReturn getDOC(@RequestBody MailEntity mailEntity, HttpServletRequest request, HttpServletResponse response, HttpSession httpSession){        log.info("excute controllor HomeController.getDOC");

    就这么多了吧,在网上看到还有添加过滤器的,当然都是差不多的做法。

转载于:https://www.cnblogs.com/yun965861480/p/6023905.html

你可能感兴趣的文章
C# Dynamic通用反序列化Json类型并遍历属性比较
查看>>
前台freemark获取后台的值
查看>>
Spring-hibernate整合
查看>>
c++ map
查看>>
exit和return的区别
查看>>
Django 相关
查看>>
Python(软件目录结构规范)
查看>>
codeforces水题100道 第二十二题 Codeforces Beta Round #89 (Div. 2) A. String Task (strings)
查看>>
c++||template
查看>>
条件断点 符号断点
查看>>
.net学习之继承、里氏替换原则LSP、虚方法、多态、抽象类、Equals方法、接口、装箱拆箱、字符串------(转)...
查看>>
python的多行注释
查看>>
连接Oracle需要jar包和javadoc文档的下载
查看>>
UVA 10976 - Fractions Again?!
查看>>
Dreamweaver cc新版本css单行显示
查看>>
【android】安卓的权限提示及版本相关
查看>>
Java基础教程——网络基础知识
查看>>
Kruskal基础最小生成树
查看>>
【hdu 1429】胜利大逃亡(续)
查看>>
关于收费软件
查看>>