当前位置: 代码网 > it编程>编程语言>Java > SpringBoot3解决跨域请求的方案小结

SpringBoot3解决跨域请求的方案小结

2024年07月31日 Java 我要评论
在spring boot 3中,解决跨域请求(cors,cross-origin resource sharing)的问题主要有以下几种方式:1. 使用@crossorigin注解你可以直接在cont

在spring boot 3中,解决跨域请求(cors,cross-origin resource sharing)的问题主要有以下几种方式:

1. 使用@crossorigin注解

你可以直接在controller类或者具体的请求处理方法上使用@crossorigin注解来允许跨域请求。

@restcontroller  
@requestmapping("/user")  
@crossorigin(origins = "*") // 允许所有来源的请求跨域  
public class usercontroller {  
    // ...  
}

在这个例子中,@crossorigin注解被添加到了控制器类上,表示这个控制器下的所有方法都允许来自http://example.com的get和post请求。你也可以将注解添加到特定的方法上,以对该方法应用cors配置。

2. 全局配置cors

如果你希望全局配置cors,而不是在每个controller或方法上单独配置,你可以创建一个配置类来实现webmvcconfigurer接口,并重写addcorsmappings方法。

import org.springframework.context.annotation.configuration;  
import org.springframework.web.servlet.config.annotation.corsregistry;  
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;  
  
@configuration  
public class corsconfig implements webmvcconfigurer {  
  
    @override  
    public void addcorsmappings(corsregistry registry) {  
        // 添加映射路径  
        registry.addmapping("/**")  
                .allowedorigins("*") // 允许哪些域的请求,星号代表允许所有  
                .allowedmethods("post", "get", "put", "options", "delete") // 允许的方法  
                .allowedheaders("*") // 允许的头部设置  
                .allowcredentials(true) // 是否发送cookie  
                .maxage(168000); // 预检间隔时间  
    }  
}

在这个配置中,addmapping("/**")表示对所有的路径都应用cors配置。allowedorigins("*")表示允许所有来源的访问,这在生产环境中可能不是最佳实践,通常你会指定具体的域名。allowedmethods定义了允许的http方法,allowedheaders定义了允许的http头部,allowcredentials(true)表示是否允许携带凭证(cookies, http认证及客户端ssl证明等),maxage则用于设置预检请求的有效期。

3. 使用filter实现cors

你也可以通过实现filter接口来自定义cors处理逻辑。

import javax.servlet.*;  
import javax.servlet.http.httpservletresponse;  
import java.io.ioexception;  
  
public class simplecorsfilter implements filter {  
  
    @override  
    public void dofilter(servletrequest req, servletresponse res, filterchain chain)  
            throws ioexception, servletexception {  
        httpservletresponse response = (httpservletresponse) res;  
        response.setheader("access-control-allow-origin", "http://example.com");  
        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");  
        chain.dofilter(req, res);  
    }  
  
    @override  
    public void init(filterconfig filterconfig) {}  
  
    @override  
    public void destroy() {}  
}

然后需要在配置类中注册这个filter。

import org.springframework.boot.web.servlet.filterregistrationbean;  
import org.springframework.context.annotation.bean;  
import org.springframework.context.annotation.configuration;  
  
@configuration  
public class filterconfig {  
  
    @bean  
    public filterregistrationbean<simplecorsfilter> corsfilter() {  
        filterregistrationbean<simplecorsfilter> registrationbean = new filterregistrationbean<>();  
        registrationbean.setfilter(new simplecorsfilter());  
        registrationbean.addurlpatterns("/*");  
        return registrationbean;  
    }  
}

4. 使用拦截器(interceptor)

如果需要更复杂的cors逻辑,你可以创建一个拦截器来处理cors请求。拦截器允许你在请求处理之前或之后添加逻辑。

import org.springframework.web.servlet.handlerinterceptor;  
import javax.servlet.http.httpservletrequest;  
import javax.servlet.http.httpservletresponse;  
  
public class corsinterceptor implements handlerinterceptor {  
  
    @override  
    public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) {  
        response.setheader("access-control-allow-origin", "http://example.com");  
        response.setheader("access-control-allow-methods", "get, post, put, delete");  
        response.setheader("access-control-allow-headers", "*");  
        // 其他cors相关的响应头设置  
        return true;  
    }  
}

然后,你需要在配置类中注册这个拦截器: 

import org.springframework.beans.factory.annotation.autowired;  
import org.springframework.context.annotation.configuration;  
import org.springframework.web.servlet.config.annotation.interceptorregistry;  
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;  
  
@configuration  
public class webconfig implements webmvcconfigurer {  
  
    @autowired  
    private corsinterceptor corsinterceptor;  
  
    @override  
    public void addinterceptors(interceptorregistry registry) {  
        registry.addinterceptor(corsinterceptor).addpathpatterns("/**");  
    }  
}
  • 当设置allowedheaders("*")时,实际上浏览器会发送实际请求头而不是*。出于安全考虑,最好明确指定允许的头部。
  • 在生产环境中,确保不要过于宽松地配置cors,只允许必要的源和方法。
  • 如果你的应用部署在代理服务器后面(如nginx或apache),可能还需要在代理服务器上配置cors。

5. 响应体(response body)来设置cors

虽然这种方式不如前面提到的几种方法直接和常用,但在某些特殊场景下,你可能需要手动控制响应头来实现跨域。

具体实现时,你可以在controller的方法中,通过httpservletresponse对象来设置access-control-allow-origin等cors相关的http头。

import javax.servlet.http.httpservletresponse;  
import org.springframework.web.bind.annotation.getmapping;  
import org.springframework.web.bind.annotation.restcontroller;  
  
@restcontroller  
public class mycontroller {  
  
    @getmapping("/data")  
    public string getdata(httpservletresponse response) {  
        // 设置允许跨域的来源  
        response.setheader("access-control-allow-origin", "http://example.com");  
        // 设置允许的方法(get, post, put, delete等)  
        response.setheader("access-control-allow-methods", "get, post, put, delete");  
        // 设置允许的头信息  
        response.setheader("access-control-allow-headers", "*");  
        // 设置预检请求的有效期  
        response.setheader("access-control-max-age", "3600");  
          
        // 返回数据  
        return "data";  
    }  
}

需要注意的是,手动设置响应头的方式相对繁琐,且容易遗漏某些必要的头信息,导致cors配置不完整。因此,在实际开发中,推荐使用前面提到的方法,它们更为直接且易于管理。

此外,如果你正在使用spring security,还需要确保spring security的配置不会阻止跨域请求的处理。在某些情况下,你可能需要在spring security的配置中允许特定的cors请求。

6. 通过自定义responsebodyadvice

responsebodyadvice是spring mvc提供的一个接口,允许你在controller方法返回响应体之前对其进行修改。虽然它本身不是专为cors设计的,但你可以利用它在返回响应之前添加cors相关的http头。

下面是一个简单的示例,展示了如何通过实现responsebodyadvice接口来添加cors头:

import org.springframework.core.methodparameter;  
import org.springframework.http.mediatype;  
import org.springframework.http.server.serverhttprequest;  
import org.springframework.http.server.serverhttpresponse;  
import org.springframework.web.servlet.mvc.method.annotation.responsebodyadvice;  
  
import java.lang.reflect.type;  
  
public class corsresponsebodyadvice implements responsebodyadvice<object> {  
  
    @override  
    public boolean supports(methodparameter returntype, class<? extends httpmessageconverter<?>> convertertype) {  
        // 支持所有返回类型  
        return true;  
    }  
  
    @override  
    public object beforebodywrite(object body, methodparameter returntype, mediatype selectedcontenttype,  
                                   class<? extends httpmessageconverter<?>> selectedconvertertype,  
                                   serverhttprequest request, serverhttpresponse response) {  
        // 设置cors相关的http头  
        response.getheaders().set("access-control-allow-origin", "http://example.com");  
        response.getheaders().set("access-control-allow-methods", "get, post, put, delete");  
        response.getheaders().set("access-control-allow-headers", "*");  
        // 如果有需要,还可以设置其他cors相关的头,比如预检请求的有效期等  
          
        // 返回原始的body,不做修改  
        return body;  
    }  
}

然后,你需要在spring boot的配置中注册这个responsebodyadvice

import org.springframework.context.annotation.configuration;  
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;  
  
@configuration  
public class webconfig implements webmvcconfigurer {  
  
    @override  
    public void configuremessageconverters(list<httpmessageconverter<?>> converters) {  
        // 注册你的responsebodyadvice  
        converters.foreach(converter -> {  
            if (converter instanceof mappingjackson2httpmessageconverter) {  
                ((mappingjackson2httpmessageconverter) converter).setresponsebodyadvice(new corsresponsebodyadvice());  
            }  
        });  
    }  
}

这种方法的优点在于它可以全局地应用于所有controller的响应,而无需在每个controller或方法上单独设置。然而,它同样也有一些局限性,比如你可能需要手动处理一些cors的细节,并且这种方式不如使用spring提供的cors支持那么直接和灵活。

在选择解决方案时,应该根据项目的具体需求和团队的偏好来权衡各种方法的优缺点。如果项目中有大量的controller需要处理跨域请求,并且希望有一个统一且全局的解决方案,那么使用webmvcconfigurer或corsfilter可能是更好的选择。如果只需要在特定的controller或方法上处理跨域请求,那么使用@crossorigin注解可能更为简单直接。

以上就是springboot3解决跨域请求的方案小结的详细内容,更多关于springboot3跨域请求的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com