跨域CORS圖片上傳問題
異常問題
專案中存在跨域圖片上傳請求,提示下列錯誤
Access to XMLHttpRequest at ‘http://localhost:8080/common/uploadPic’ from origin 'http://localhost:8000’has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.
最初的跨域支援使用spring
提供的註解 @CrossOrigin
來處理,針對專案中普通介面 @CrossOrigin
註解的預設策略已經可以滿足,唯獨對於圖片上傳請求無法支援。
檢視 Spring CORS
支援文件,@CrossOrigin
註解預設策略支援所有的origins
以及 GET
、HEAD
、POST
三種請求方法。
In addition to fine-grained, annotation-based configuration you’ll probably want to define some global CORS configuration as well. This is similar to using filters but can be declared withing Spring MVC and combined with fine-grained
@CrossOrigin
configuration. By default all origins andGET
,HEAD
andPOST
methods are allowed.
CORS機制
CORS請求
瀏覽器將 CORS
請求分成兩類:簡單請求( simple request
)和非簡單請求( not-so-simple request
)。
只要同時滿足以下兩大條件,就屬於簡單請求。(引用自跨域資源共享 CORS 詳解)
(1) 請求方法是以下三種方法之一:
- HEAD
- GET
- POST
(2)HTTP的頭資訊不超出以下幾種欄位:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限於三個值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
預檢請求
因為前端H5頁面請求時新增了全域性配置 Content-Type
為 application/json
,不符合上述簡單請求條件,屬於非簡單請求,因此會新增預檢 OPTIONS
請求
預檢 OPTIONS
請求 header
資訊
Request Method: OPTIONS
Access-Control-Request-Headers: x-requested-with
Access-Control-Request-Method: POST
Origin: http://test.demo.com:59004
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36
預檢請求響應
瀏覽器收到預檢請求響應後,會檢查 Access-Control-Allow-Origin
、Access-Control-Allow-Methods
、Access-Control-Allow-Headers
確認允許跨域請求。
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: x-requested-with
Access-Control-Allow-Methods: GET,POST,OPTIONS
Access-Control-Allow-Origin: http://test.demo.com:59004
Connection: keep-alive
Content-Length: 0
Date: Thu, 01 Nov 2018 07:06:30 GMT
Server: nginx
Vary: Origin
異常解決
因此決定在 @CrossOrigin
註解中配置支援 OPTIONS
請求,再次本地測試跨域圖片上傳,可以成功上傳。
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.OPTIONS})
但是部署測試環境之後,發現了另一個潛在的問題,登入環境開啟了登入攔截,會使用 cookie
中登入資訊檢驗登入,當登入資訊在有效期內,所有介面都能正常跨域請求使用。但登入資訊失效後,導致所有的介面包括圖片上傳都提示開頭的跨域問題,懷疑是 @CrossOrigin
註解的執行順序在登入攔截器之後,當請求被攔截器攔截,因為還未執行 @CrossOrigin
跨域支援邏輯,導致響應就存在異常,也不能正確跳轉登入頁面。因此嘗試尋找另外的跨域處理方式,在 Spring CORS
支援文件中提供了Spring Boot應用基於 Filter
方式的全域性跨域支援。
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod(HttpMethod.GET);
config.addAllowedMethod(HttpMethod.POST);
config.addAllowedMethod(HttpMethod.OPTIONS);
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
修改為 Filter
全域性跨域支援後,再次測試包括登入有效期內及登入失效情況下圖片上傳和其它常規介面,都能正常處理,登入失效時也能正常返回跳轉登入的業務狀態碼。
參考資料
CORS Support in Spring Framework
http://www.ruanyifeng.com/blog/2016/04/cors.html
相關文章
- CORS跨域問題梳理CORS跨域
- cors解決跨域問題CORS跨域
- 解決CORS跨域不能傳遞cookies的問題CORS跨域Cookie
- 深入跨域問題(2) - 利用 CORS 解決跨域跨域CORS
- Nginx解決前端跨域問題 CORS跨域配置Nginx前端跨域CORS
- nginx 解決圖片跨域問題Nginx跨域
- Cors跨域問題中文官方文件CORS跨域
- 跨域問題,解決方案 – CORS方案跨域CORS
- 深入跨域問題(1) - 初識 CORS 跨域資源共享跨域CORS
- 前端常見問題——Canvas 圖片跨域前端Canvas跨域
- wangEditor上傳圖片問題
- 跨域問題(CORS / Access-Control-Allow-Origin)跨域CORS
- 解決跨域問題 barryvdh/Laravel-cors跨域LaravelCORS
- 搞定所有的跨域請求問題: jsonp & CORS跨域JSONCORS
- SpringBoot中通過CORS解決跨域問題Spring BootCORS跨域
- has been blocked by CORS policy跨域問題解決BloCCORS跨域
- 跨域CORS跨域CORS
- CORS跨域CORS跨域
- vue如何使用富文字編輯器wangEditor自定義圖片上傳(解決跨域問題)Vue跨域
- laravel上傳圖片路徑問題Laravel
- Spring boot 和Vue開發中CORS跨域問題Spring BootVueCORS跨域
- 跨域 Cors error跨域CORSError
- 跨域之CORS跨域CORS
- springboot配置CORS允許跨域訪問Spring BootCORS跨域
- CORS跨域請求CORS跨域
- JavaScript-CORS 跨域JavaScriptCORS跨域
- 阿里雲圖片跨域訪問設定阿里跨域
- 有關laravel 上傳圖片訪問404的問題Laravel
- 跨域問題(普通跨域和springsecurity跨域)跨域SpringGse
- 跨域資源共享CORS跨域CORS
- 跨域資源共享——CORS跨域CORS
- 跨域資源共享(CORS)跨域CORS
- 跨域共享CORS詳解及Gin配置跨域跨域CORS
- canvas簽名圖片上傳及入庫問題Canvas
- 跨域問題跨域
- Ajax與Flask傳值的跨域問題Flask跨域
- 過濾器解決檔案上傳下載跨域問題過濾器跨域
- 解決canvas合成圖片大小錯誤、模糊以及跨域的問題Canvas跨域