首頁  >  文章  >  Java  >  Spring Boot:如何解決跨來源問題

Spring Boot:如何解決跨來源問題

DDD
DDD原創
2024-09-12 22:15:02745瀏覽

Spring Boot: How to Solve Cross-Origin Issues

跨源問題描述

您可能會遇到以下錯誤訊息:

被 CORS 政策阻止:請求的資源上不存在「Access-Control-Allow-Origin」標頭

此錯誤表示對某個位址的請求已被 CORS 協定阻止,因為資源中缺少 Access-Control-Allow-Origin 標頭。

分析跨源問題

跨網域問題的根本原因是瀏覽器出於安全考慮,限制存取目前網站以外的資源。

例如,考慮託管在 http://127.0.0.1:8080/ 且具有特定頁面的網站。如果您從同一網站存取資源,則沒有任何限制。但如果您嘗試從其他網站存取資源(例如http://127.0.0.1:8081),瀏覽器將阻止該要求。

注意:我們將協定、域和連接埠視為定義「同源」的一部分。

具有 src 屬性的元素,例如 img 和 script 標籤,不受此限制。

歷史上,當前端和後端不分離時,頁面和請求介面存在於同一個網域和連接埠下。然後,瀏覽器將允許來自一個網域託管的頁面的請求從同一網域請求資源。

例如http://127.0.0.1:8080/index.html可以自由要求http://127.0.0.1:8080/a/b/c/userLit。

現在,前端和後端分離到不同的應用程式中,這是不允許的,並且會引發 CORS 問題。

什麼是起源和跨起源?

來源(或來源)由協定、網域和連接埠號碼組成。

URL 由協定、網域、連接埠和路徑組成。如果兩個 URL 的協定、網域和連接埠都相同,則它們被視為「同源」。這三個元素中任何一個的差異都構成跨源請求。

考慮 https://www.baidu.com/index.html 的跨域比較:

URL Cross-Origin Reason
https://www.baidu.com/more/index.html No Same protocol, domain, and port
https://map.baidu.com/ Yes Different domain
http://www.baidu.com/index.html Yes Different protocol
https://www.baidu.com:81/index.html Yes Different port

What is the Same-Origin Policy?

The Same-Origin Policy is a fundamental browser security feature. Without it, the normal functionality of browsers could be at risk. Web architecture heavily depends on this policy, and browsers implement it to ensure security.

The Same-Origin Policy includes:

  1. DOM Same-Origin Policy: Prevents DOM manipulation of different origin pages. Applies mainly to cross-origin iframe scenarios where different domains' iframes can't access each other.
  2. XMLHttpRequest Same-Origin Policy: Prohibits HTTP requests to different origins using XHR objects.

Solving Cross-Origin Issues in Spring Boot

1. Creating a Filter to Handle CORS

In a project where the front-end and back-end are deployed separately, addressing CORS is crucial. Cookies are used to store user login information, and Spring interceptors manage permissions. Issues arise when the interceptor and CORS are processed in the wrong order, causing a CORS error.

An HTTP request first goes through the filter before reaching the servlet and then the interceptor. To ensure CORS processing occurs before authorization interception, we can place the CORS configuration in a filter.

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}

2. Configuring CORS in WebMvcConfigurer

While JSONP can address cross-origin issues on the front-end, it only supports GET requests, which is limiting in RESTful applications. Instead, you can handle cross-origin requests with Cross-Origin Resource Sharing (CORS) on the back-end. This solution is not unique to Spring Boot and has been used in traditional SSM frameworks. You configure it by implementing the WebMvcConfigurer interface and overriding the addCorsMappings method.

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .maxAge(3600);
    }
}

3. Configuring CORS in Controller

You can enable CORS for specific controller methods by adding the @CrossOrigin annotation to the @RequestMapping annotation. By default, @CrossOrigin allows all origins and HTTP methods specified in @RequestMapping.

@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin
    @GetMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Understanding @CrossOrigin Parameters:

  • @CrossOrigin without parameters allows all URLs to access.
  • @CrossOrigin(origins = "http://127.0.0.1:8080") restricts access to the specified URL.
  • This annotation can be used on classes or methods.
  • The value or origins attribute specifies allowed URLs.
  • maxAge indicates the maximum age in seconds for the preflight request cache.
  • allowCredentials indicates if credentials (cookies) are allowed. Default is false.
  • allowedHeaders specifies allowed request headers.
  • methods specifies allowed request methods, default being GET, POST, HEAD.

Reasons @CrossOrigin Might Not Work

  1. Spring MVC version must be 4.2 or higher to support @CrossOrigin.
  2. Incorrect requests might appear as cross-origin issues due to improper server response.
  3. If adding @CrossOrigin above the Controller annotation still results in issues, one possible fix is to specify the HTTP methods in @RequestMapping.

Example:

@CrossOrigin
@RestController
public class PersonController {

    @RequestMapping(method = RequestMethod.GET)
    public String add() {
        // some code
    }
}

以上是Spring Boot:如何解決跨來源問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn