跨域那点事~

本文介绍了解决前后端分离项目中的跨域问题的多种方法。包括使用JSONP方式、通过后台添加响应头允许跨域访问、SpringBoot配置跨域支持及使用@CrossOrigin注解等方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自从做了前后端分离项目以后,就遇到了跨域问题.一直也没有深入自己去测试,反正能解决就行了,今天自己写了一系列测试,得到了java解决跨域问题的多种方法;

1.首先是基本没用过的jsonp方式:(缺点:麻烦,只支持GET请求)

     $("#btn3").click(function () {
            $.ajax({
                url: "http://localhost:9090/test3",
                type: "get",
                dataType: "jsonp",            //这里指定请求后台服务器返回类型jsonp
            //    jsonpCallback: "gao",       //指定请求地址后面callback的值
            //    jsonp:"callback",           //指定jsonp请求地址的参数名,默认callback
                success: function (data) {
                    alert(data);
                }
            });
        });

如果上面不指定jsonpCallback的请求值时,会默认生成随机的请求值;如下:

http://localhost:9090/test3?callback=jsonp1536806347498

后台处理的话,就要在参数返回时,使用jsonp请求值包裹返回值,如 jsonp1536806347498(...);

    @GetMapping("/test3")
    public void tt3e(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String callback = request.getParameter("callback");
        String result = new ObjectMapper().writeValueAsString(Arrays.asList(1, 1, 1, 1));
        String now = callback + "(" + result + ")";
        response.getWriter().write(now);
    }

2.后台返回参数header添加跨域参数;(全是优点)

这种前台不用做任何操作,只要后台进行一些添加参数即可;方式有以下几种;

第一种,添加过滤器,拦截器方式:

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setCharacterEncoding("utf-8");
        response.setHeader("Access-Control-Allow-Origin", "*"); // 解决跨域访问报错
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600"); // 设置过期时间
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1.
        response.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0. response.setHeader("Expires", "0");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}
public class MyConfig implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            response.setHeader("Access-Control-Allow-Origin", "*");  
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,             DELETE");  
            response.setHeader("Access-Control-Max-Age", "3600");  
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); 
        return true;
    }
}

这种方式不管你已何种方式请求,跨域或者不跨域,在返回参数header参数中,都可以看到以下参数:

Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Cache-Control: no-cache, no-store, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Thu, 13 Sep 2018 02:50:53 GMT
Pragma: no-cache
Transfer-Encoding: chunked

因为用下面的方式跨域时,本地用postman测试时候,因为没有这些参数,一直以为没有生效,所以一直采用这种方式,没有敢用其他方式.......其实下面方式也是生效的,只有跨域请求的时候会在返回参数中带有这些跨域参数;

第二种,springboot直接重写跨域配置,这种方式比较简单,推荐:

public class MyCros implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*");
    }
}

第三种:在类或者方法上添加@CrossOrigin注解;看到网上有在ssm项目中遇到不生效的问题,看到解决办法有的因为@RequestMapping注解中没有指定method请求方式造成的,只要添加get或post等参数就可以了.我在springboot中没有出现这种问题;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值