1. 程式人生 > >SpringBoot:SpringBoot專案中跨域問題的解決

SpringBoot:SpringBoot專案中跨域問題的解決

SpringBoot:SpringBoot專案中跨域問題的解決

出於安全原因,瀏覽器禁止對駐留在當前源之外的資源進行AJAX呼叫。

跨源資源共享(CORS)是大多數瀏覽器實現的W3C規範,允許以靈活的方式指定授權的跨域請求型別,而不是使用IFrame或JSONP等安全性較低且功能較弱的黑客。

Spring Framework 4.2 GA為開箱即用的CORS提供了一流的支援,提供了比典型的基於過濾器的解決方案更簡單,更強大的配置方式。

方法一、使用@Configuration註解編寫配置類(一)

/**
 * 
 * 設定跨域請求的配置類
 */
@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        	// 1. 設定訪問源地址
        	corsConfiguration.addAllowedOrigin("*"); 
        	// 2. 設定訪問源請求頭
        	corsConfiguration.addAllowedHeader("*"); 
        	 // 3. 設定訪問源請求方法
        	corsConfiguration.addAllowedMethod("*");
        
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        	// 4. 對介面配置跨域設定
        	source.registerCorsConfiguration("/**", buildConfig()); 
        	
        return new CorsFilter(source);
    }
}

方法一、使用@Configuration註解編寫配置類(二)

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                //registry.addMapping("/**");
                registry.addMapping("/api/**")
					    .allowedOrigins("http://domain2.com")
						.allowedMethods("PUT", "DELETE")
						.allowedHeaders("header1", "header2", "header3")
						.exposedHeaders("header1", "header2")
						.allowCredentials(false).maxAge(3600);
            }
        };
    }
}

在上述程式碼中“ * ”代表全部。” ** ”代表適配所有介面。
其中addAllowedOrigin(String origin)方法是追加訪問源地址。如果不使用”*”(即允許全部訪問源),則可以配置多條訪問源來做控制。
例如:

corsConfiguration.addAllowedOrigin("http://www.a.cn/"); 
corsConfiguration.addAllowedOrigin("http://test.b.cn/"); 

CorsConfiguration類的官方文件中除了addAllowedOrigin(String origin)方法,還有setAllowedOrigins(List allowedOrigins)方法,其實現如下:

public void setAllowedOrigins(List<String> allowedOrigins) {
	this.allowedOrigins = allowedOrigins != null?new ArrayList(allowedOrigins):null;
}

addAllowedOrigin是追加訪問源地址,而setAllowedOrigins是可以直接設定多條訪問源。
根據上述原始碼可以得知,setAllowedOrigins會覆蓋this.allowedOrigins。所以在配置訪問源地址時, addAllowedOrigin方法要寫在setAllowedOrigins後面,當然了,一般情況下不建議這兩個方法混著用。

addAllowedHeader、addAllowedMethod、registerCorsConfiguration方法和addAllowedOrigin的原始碼類似,這裡就不一一介紹了。

方法二、在Controller層使用@CrossOrgin註解配置

@CrossOrgin註解既可以用於方法也可以用於整個Controller層。
當控制器和方法均有CORS配置時,Spring將組合兩個註釋屬性以建立合併的CORS配置。
1.用於控制器
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

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

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

2.用於方法

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

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

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

3.控制器和方法均有

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

	@CrossOrigin(origins = "http://domain2.com")
	@GetMapping("/{id}")
	public Account retrieve(@PathVariable Long id) {
		// ...
	}

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

如果使用的是Spring Security,必須確保在Spring Security級別啟用CORS,以允許它利用Spring MVC級別定義的配置。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.cors().and()...
	}
}