跨域問題(CORS / Access-Control-Allow-Origin)
1、前言
最近在專案中,呼叫Eureka REST介面時,出現了CORS跨越問題(Cross-origin resource sharing),在此與大家進行分享,避免多走些彎路。
專案前端(http://localhost:9000)通過Ajax方式呼叫Eureka REST 介面(http://localhost:8761/eureka/apps)時,卻沒有任何反應,則通過F12檢視日誌發現出現“Access-Control-Allow-Origin“類 異常,詳細如下:
…… http://localhost:8761/eureka/apps. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin……
通過google,發現是由於CORS跨越問題造成的,解決辦法無非有兩種方式:響應頭新增引數和新增過濾器,下面就詳細說說CORS跨越問題的起因與詳細解決辦法。
2、CORS
CORS,常被大家稱之為跨越問題,準確的叫法是跨域資源共享(CORS,Cross-origin resource sharing),是W3C標準,是一種機制,它使用額外的HTTP頭來告訴瀏覽器 讓執行在一個 origin (domain) 上的Web應用被准許訪問來自不同源伺服器上的指定的資源。當一個資源從與該資源本身所在的伺服器不同的域或埠請求一個資源時,資源會發起一個跨域 HTTP 請求。
http://localhost:9000請求http://localhost:8761/eureka/apps就是違背了上述原則,即:請求伺服器不同埠的另一個資源,出於安全原因,瀏覽器限制發起的跨源HTTP請求,則會出現本文開頭提到的現象及異常。
例如,XMLHttpRequest和Fetch API遵循同源策略, 這意味著使用這些API的Web應用程式只能從載入應用程式的同一個域請求HTTP資源,除非使用CORS頭。
跨域資源共享( CORS )機制允許 Web 應用伺服器進行跨域訪問控制,從而使跨域資料傳輸得以安全進行。瀏覽器支援在 API 容器中(例如 XMLHttpRequest
或 Fetch )使用 CORS,以降低跨域 HTTP 請求所帶來的風險。
什麼情況下存在跨域問題
- 本文提到的由 XMLHttpRequest 或 Fetch 發起的跨域 HTTP 請求。
- Web 字型 (CSS 中通過 @font-face 使用跨域字型資源),,因此,網站就可以釋出 TrueType 字型資源,並只允許已授權網站進行跨站呼叫。
- WebGL 貼圖。
- 使用 drawImage 將 Images/video 畫面繪製到 canvas
- 樣式表(使用 CSSOM)。
面對CORS的限制,將如何解決呢
世間萬物完事,有因必有果,有果必有因。當然CORS的限制,官方也是給出瞭解決辦法的。
CORS標準新增了一組 HTTP 頭欄位(Access-Control-Allow-Origin),允許伺服器宣告哪些源通過瀏覽器有許可權訪問哪些資源。另外,規範要求,對那些可能對伺服器資料產生副作用的 HTTP 請求方法(特別是 GET以外的 HTTP 請求,或者搭配某些 MIME 型別的 POST請求),瀏覽器必須首先使用 OPTIONS
方法發起一個預檢請求(preflight request),從而獲知服務端是否允許該跨域請求。伺服器確認允許之後,才發起實際的 HTTP 請求。在預檢請求的返回中,伺服器端也可以通知客戶端,是否需要攜帶身份憑證(包括Cookies 和 HTTP 認證相關資料)。
CORS請求失敗會產生錯誤,但是為了安全,在JavaScript程式碼層面是無法獲知到底具體是哪裡出了問題。你只能檢視瀏覽器的控制檯以得知具體是哪裡出現了錯誤。
如果有興趣瞭解該機制剖析的可以參考https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
3、解決辦法
在查閱大量資源,並瞭解過CORS機制後,解決辦法實質必定會圍繞Access-Control-Allow-Origin頭。
解決辦法如下:
新增響應頭
在被請求資源中新增響應頭資訊"Access-Control-Allow-Origin:*
過濾器
在本專案中新增如下過濾器:
/**
* 解決跨域問題
*/
public class AccessControlAllowOriginFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, response);
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}
註解方式
在Spring Boot中擁有大量的註解,針對跨域問題,也提供了對應的註解@CrossOrigin,使用方法如下:
import java.util.HashMap;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author xcbeyond
*/
@RestController
@RequestMapping(value = "/api", method = RequestMethod.POST)
public class DemoController {
@CrossOrigin(origins = "*")
@RequestMapping(value = "/get")
public String get() {
……
}
}
個人比較推薦使用上述的三種方式之一,其他方式請自己百度、谷歌吧
相關文章
- CORS跨域問題梳理CORS跨域
- cors解決跨域問題CORS跨域
- Nginx解決前端跨域問題 CORS跨域配置Nginx前端跨域CORS
- 深入跨域問題(2) - 利用 CORS 解決跨域跨域CORS
- 跨域問題,解決方案 – CORS方案跨域CORS
- 跨域CORS圖片上傳問題跨域CORS
- Cors跨域問題中文官方文件CORS跨域
- 跨域問題,解決方案 - CORS方案跨域CORS
- 深入跨域問題(1) - 初識 CORS 跨域資源共享跨域CORS
- 解決跨域問題 barryvdh/Laravel-cors跨域LaravelCORS
- WebApi 跨域問題解決方案(3):CORSWebAPI跨域CORS
- 跨域CORS跨域CORS
- CORS跨域CORS跨域
- has been blocked by CORS policy跨域問題解決BloCCORS跨域
- 跨域之CORS跨域CORS
- 跨域 Cors error跨域CORSError
- 解決CORS跨域不能傳遞cookies的問題CORS跨域Cookie
- 搞定所有的跨域請求問題: jsonp & CORS跨域JSONCORS
- Gitea CORS Access-Control-Allow-Origin 的問題GitCORS
- Spring boot 和Vue開發中CORS跨域問題Spring BootVueCORS跨域
- SpringBoot中通過CORS解決跨域問題Spring BootCORS跨域
- JavaScript-CORS 跨域JavaScriptCORS跨域
- CORS跨域請求CORS跨域
- Apache解決Access-Control-Allow-Origin多域名跨域問題Apache跨域
- 跨域資源共享(CORS)跨域CORS
- 跨域資源共享CORS跨域CORS
- 跨域資源共享——CORS跨域CORS
- CORS 跨域資源共享CORS跨域
- CORS跨域cookie傳遞CORS跨域Cookie
- CORS跨域資源共享CORS跨域
- NodeJS+Express解決跨域問題:Access-Control-Allow-OriginNodeJSExpress跨域
- No 'Access-Control-Allow-Origin' header: 跨域問題踩坑記錄Header跨域
- 跨域共享CORS詳解及Gin配置跨域跨域CORS
- springboot配置CORS允許跨域訪問Spring BootCORS跨域
- 跨域問題跨域
- 跨域問題(普通跨域和springsecurity跨域)跨域SpringGse
- nginx配置CORS實現跨域NginxCORS跨域
- CORS跨域請求總結CORS跨域