說到跨域訪問,必須先解釋一個名詞:同源策略。所謂同源策略就是在瀏覽器端出於安全考量,向服務端發起請求必須知足:協議相同、Host(ip)相同、端口相同的條件,不然訪問將被禁止,該訪問也就被稱爲跨域訪問。
雖然跨域訪問被禁止以後,能夠在必定程度上提升了應用的安全性,但也爲開發帶來了必定的麻煩。好比:咱們開發一個先後端分離的易用,頁面及js部署在一個主機的nginx服務中,後端接口部署在一個tomcat應用容器中,當前端向後端發起請求的時候必定是不符合同源策略的,也就沒法訪問。那麼咱們如何解決這個問題?就是本文須要向你們說明的內容。css
雖然瀏覽器對於不符合同源策略的訪問是禁止的,可是仍然存在例外的狀況,如如下資源引用的標籤不受同源策略的限制:html
除了基於HTML自己的特性實現跨域訪問,咱們還可使用jsonp、window的postMessage實現跨域訪問。這些都是前端實現跨域訪問的方式。前端
實際上對跨域訪問的支持在服務端實現起來更加容易,最經常使用的方法就是經過代理的方式,如:node
其實實現代理跨域的邏輯很是簡單:就是在不一樣的資源服務:js資源、html資源、css資源、接口數據資源服務的前端搭建一箇中間層,全部的瀏覽器及客戶端訪問都經過代理轉發。因此在瀏覽器、客戶端看來,它們訪問的都是同一個ip、同一個端口的資源,從而符合同源策略實現跨域訪問。nginx
跨域資源共享(CORS):經過修改Http協議header的方式,實現跨域。說的簡單點就是,經過設置HTTP的響應頭信息,告知瀏覽器哪些狀況在不符合同源策略的條件下也能夠跨域訪問,瀏覽器經過解析Http協議中的Header執行具體判斷。具體的Header以下: ajax
CROS跨域經常使用headerspring
Accept
、Accept-Language
、Content-Language
、Content-Type
爲你們介紹四種實現CORS的方法,兩種是全局配置,兩種是局部接口生效的配置。通常來講,SpringBoot項目採用其中一種方式實現CORS便可。json
@Configuration public class GlobalCorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); //開放哪些ip、端口、域名的訪問權限,星號表示開放全部域 config.addAllowedOrigin("*"); //是否容許發送Cookie信息 config.setAllowCredentials(true); //開放哪些Http方法,容許跨域訪問 config.addAllowedMethod("GET","POST", "PUT", "DELETE"); //容許HTTP請求中的攜帶哪些Header信息 config.addAllowedHeader("*"); //暴露哪些頭部信息(由於跨域訪問默認不能獲取所有頭部信息) config.addExposedHeader("*"); //添加映射路徑,「/**」表示對全部的路徑實行全局跨域訪問權限的設置 UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); return new CorsFilter(configSource); } }
@Configuration public class GlobalCorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") //添加映射路徑,「/**」表示對全部的路徑實行全局跨域訪問權限的設置 .allowedOrigins("*") //開放哪些ip、端口、域名的訪問權限 .allowCredentials(true) //是否容許發送Cookie信息 .allowedMethods("GET","POST", "PUT", "DELETE") //開放哪些Http方法,容許跨域訪問 .allowedHeaders("*") //容許HTTP請求中的攜帶哪些Header信息 .exposedHeaders("*"); //暴露哪些頭部信息(由於跨域訪問默認不能獲取所有頭部信息) } }; } }
@RequestMapping("/cors") @ResponseBody @CrossOrigin(origins = "http://localhost:8080", maxAge = 3600) public String cors( ){ return "cors"; }
這種方式略顯麻煩,不建議在SpringBoot項目中使用。segmentfault
@RequestMapping("/cors") @ResponseBody public String cors(HttpServletResponse response){ //使用HttpServletResponse定義HTTP請求頭,最原始的方法也是最通用的方法 response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080"); return "cors"; }
在SpringBoot項目外隨便定義一個HTML,並寫代碼觸發以下的ajax代碼。(觸發過程我就不寫了,定義一個按鈕加一個監聽函數便可)。如下是跨域AJAX請求驗證的核心代碼:後端
$.ajax({ url: 'http://localhost:8090/cors', type: "POST", xhrFields: { withCredentials: true //容許發送Cookie信息 }, success: function (data) { alert("跨域請求配置成功") }, error: function (data) { alert("跨域請求配置失敗") } })