跨域介绍及Java中常见的跨域解决方案

介绍

跨域(Cross-Origin)指的是在浏览器中,由于安全策略的限制,当前网页的 JavaScript 代码无法直接访问不同源(协议、域名、端口)的资源。这意味着如果网页尝试通过 AJAX、Fetch 或 WebSocket 等方式向不同源的服务器发送请求,浏览器会阻止这些请求,从而避免潜在的安全风险。

产生原因

浏览器同源策略(Same-Origin Policy)是一种安全机制,用于限制从一个源加载的文档或脚本如何与来自其他源的资源进行交互。同源策略的目的是保护用户隐私和防止恶意代码的执行。

同源策略要求两个 URL 的协议、主机名和端口号必须完全相同,才被认为是同源。如果两个 URL 的协议、主机名或端口号之一不同,就会被视为跨源请求,那么在默认情况下,浏览器会阻止跨源请求的访问。

同源策略限制了以下几个方面的跨源行为:

  1. DOM 访问限制:跨源的 JavaScript 无法访问不同源页面的 DOM 结构。

  2. 数据访问限制:跨源的 JavaScript 无法读取不同源的数据,如读取 Cookies、LocalStorage 或发送 AJAX 请求。

  3. 脚本执行限制:无法加载不同源的 JavaScript 脚本。

为了允许某些跨源行为,浏览器提供了一些机制,如跨域资源共享(CORS)和 JSONP。这些机制通过特定的头部字段或动态创建 script 标签来允许跨源请求。

需要注意的是,同源策略仅在浏览器环境中起作用,对于服务器端和其他环境并不适用。服务器端可以通过其他方式进行跨域访问,如代理服务器或后端接口配置等。

常见解决方案

跨域限制的原因是浏览器的同源策略(Same-Origin Policy),该策略要求网页只能访问与其来源相同的资源。但是,有时候我们需要在不同源之间进行数据交互,这就需要使用跨域解决方案。

  • JSONP(JSON with Padding):通过动态创建 <script> 标签,将跨域请求数据封装在一个回调函数中返回,利用 <script> 标签的跨域特性实现数据获取。
  • CORS(Cross-Origin Resource Sharing):服务端设置相应的响应头,允许跨域访问。在服务端设置 Access-Control-Allow-Origin 头部字段,指定允许访问的域名或通配符 *。
  • 代理服务器:在同源的服务器上创建一个接口,将客户端请求发送到目标服务器,并将响应返回给客户端。客户端只与同源的服务器通信,避免了跨域问题。
  • WebSocket:使用 WebSocket 进行双向通信时,由于 WebSocket 协议的特殊性,允许跨域通信。

请注意,这些跨域解决方案各有优缺点,选择适合您需求的解决方案取决于具体情况。同时,为了确保安全性,应该仔细考虑跨域请求所带来的潜在风险,并采取适当的安全措施。

SpringBoot中CORS跨域解决

在 Spring Boot 中解决跨域问题,你可以使用 Spring 提供的 @CrossOrigin 注解或者通过配置 WebMvcConfigurer 来实现。

  1. 使用 @CrossOrigin 注解:
    在你的控制器类或方法上添加 @CrossOrigin 注解,可以指定允许访问的源、允许的 HTTP 方法、允许的请求头等。
@RestController
@CrossOrigin(origins = "http://example.com")
public class MyController {
    // ...
}

上面的示例中,允许来自 http://example.com 域名的请求访问该控制器

  1. 配置 WebMvcConfigurer:
    在你的 Spring Boot 项目中创建一个配置类,实现 WebMvcConfigurer 接口,并覆盖 addCorsMappings 方法,在该方法中配置跨域设置。

示例:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://example.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

上面的示例中,配置了允许来自 http://example.com 域名的请求访问任意路径,并允许的 HTTP 方法包括 GET、POST、PUT 和 DELETE,允许的请求头为任意头部。

  1. 使用 Filter 进行跨域设置:
    创建一个实现 javax.servlet.Filter 接口的过滤器类,然后在 doFilter 方法中设置跨域相关的响应头。

示例:

public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setHeader("Access-Control-Allow-Origin", "http://example.com");
        httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        httpResponse.setHeader("Access-Control-Allow-Headers", "*");
        chain.doFilter(request, response);
    }
}

然后在你的 Spring Boot 项目中注册该过滤器,可以通过配置类或者在 web.xml 文件中配置。

  1. Spring Security 中禁用跨域资源共享(CORS),可以使用以下配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().disable() // 禁用 CORS
            .and()
            // 其他配置项...
    }
}

通过在 configure(HttpSecurity http) 方法中调用 .cors().disable(),可以禁用 Spring Security 的 CORS 配置。这将允许跨域请求的发生而无需进行任何限制。

请注意,在禁用 CORS 后,跨域请求将不受 Spring Security 的限制,这可能会导致安全风险。建议在开发环境中使用此配置进行临时调试和测试,而在生产环境中仔细考虑跨域请求的安全控制。

  1. 使用代理服务器(如 Nginx)进行跨域设置:
    如果你的应用程序部署在代理服务器(如 Nginx)后面,你可以通过配置代理服务器来解决跨域问题。在 Nginx 配置中添加以下内容:
location / {
    add_header Access-Control-Allow-Origin http://example.com;
    add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE;
    add_header Access-Control-Allow-Headers *;
    proxy_pass http://your-backend-server;
}

上面的示例中,配置了允许来自 http://example.com 域名的请求访问,并转发到后端服务器。

常见跨域http响应头说明

在跨域请求中,常见的响应头配置包括以下几个:

  • Access-Control-Allow-Origin:指定允许访问的源(域)列表。可以设置为具体的* 域名,也可以使用通配符 “” 表示允许任意域进行访问。

  • Access-Control-Allow-Methods:指定允许的请求方法。例如,“GET, POST, * PUT, DELETE” 表示允许使用这些方法进行请求。*

  • Access-Control-Allow-Headers:指定允许的请求头信息。可以设置为具体的头部* 字段,或者使用 “” 表示允许任意头部字段。

  • Access-Control-Allow-Credentials:指定是否允许发送身份凭证(如 * cookies、HTTP 认证或客户端 SSL 证书)到跨域请求的目标服务器。如果设置为 * true,则允许发送身份凭证;如果设置为 false,则不允许发送身份凭证。*

  • Access-Control-Expose-Headers:指定允许浏览器访问的响应头信息。例如,* “Content-Type, Authorization” 表示允许访问这些响应头。*

  • Access-Control-Max-Age:指定预检请求的有效期,即在发送实际请求前,浏览器对* 该跨域请求进行预检的时间间隔。单位为秒。

以下是一个常见的跨域响应头的配置示例:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Content-Type, Authorization
Access-Control-Max-Age: 3600

版权声明:本文为博主作者:AK_GCC原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/akaiyijian001/article/details/131012474

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2024年1月8日
下一篇 2024年1月8日

相关推荐