1. 程式人生 > >配置CORS解決跨域呼叫—反思思考問題的方式

配置CORS解決跨域呼叫—反思思考問題的方式

導讀:最近都在用一套完整的Java EE的體系做系統,之前都是用spring框架,現在弄這個Java EE,覺得新鮮又刺激。但,由於之前沒有過多的研究和使用,在應用的過程中,也出現了不少的問題。累積了好幾個,現在開始一一進行總結分享。這篇部落格,主要是分享CORS解決跨域呼叫的過程

一、問題的出現

由於我們在專案中使用了一個很牛掰的外掛Jeddict,然後除了邏輯性的程式碼,其他基本的程式碼(從dao到前端Angular)都是外掛生成的,所以,我們要做的,就是連通前端Angular和後端自動生成的Restful介面。PS:對於Jeddict的問題,後續部落格中再進行說明。

最開始是把程式碼生成,然後自動構建釋出,讓區域網類的同組小夥伴呼叫測試,也用postMan進行檢測,沒有發現問題(走到這一步,也是一路坑)。後來在進行Angular服務呼叫的時候,失敗。具體錯誤資訊如下:


二、解決過程

1,首先是之前遇到過跨域問題的小夥伴,提出了一個方案,說只要在後端返回資料的時候,設定一下header就可以解決。具體程式碼如下:

 //解決跨域問題
 response.setHeader("Access-Control-Allow-Origin", "*");

但是,查了一下程式碼,發現這裡面所用到的response是HttpServletResponse型別,而現在工程裡面自動生成的程式碼,雖然也是返回一個Reponse,但這個Response和HttpServletResponse完全是兩回事。要使用這種方法解決,得引入HttpServletReponse依賴,然後在每個方法裡面增添response引數,還得修改原有的controller返回方式,也就意味著,原有系統的前端呼叫也需要重新改寫。PS: 真有一種費了死勁拆東牆補西牆的感覺。

結論:不作為首選方案

2,想到了JSONP,但JSONP的訪問方式受到了GET限制,不符合當前專案的需求。結論:不採用

3,CORS

最開始是在spring官網上找到了跨域的解決方案(團隊要求首先從官網查資料),然後大概看了看,是自己寫了個cors的filter,其實也就是配置了響應標頭,基本程式碼如下:

@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletResponse res = (HttpServletResponse)response;
		res.setHeader("Access-Control-Allow-Origin", "*");
		res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
		res.setHeader("Access-Control-Max-Age", "3600");
		res.setHeader("Access-Control-Allow-Headers", "x-requested-with");
		chain.doFilter(request, response);
	}

web.xml檔案配置
<!-- cors解決跨域訪問問題 -->
<filter>
	<filter-name>cors</filter-name>
	<filter-class>com.ustcinfo.kanms.support.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>cors</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

這個方案,測試通過。然後,其實還是有點麻煩(原諒我已經懶到了一種不可理喻的地步),也根據大哥的引導,說spring官網能提供這麼一個解決方案,java EE也可能提供一個解決方案。然後,我就去官網看了看,果然,有解決方案。具體如下:

簡單、粗暴!

最後解決了,但還出了個小毛病,報了405 (Method Not Allowed) ,我就回頭去看我的程式,發現理論上沒問題,就再看了看具體的錯誤資訊:


終於,本寶寶發現了POST,然後很確定提供服務的訪問方式是GET,問題就這麼解決了。所以,再一次提醒我自己,認真看錯誤資訊!

三、個人總結

哎,發現一個可以讓自己有所提升的點,是什麼呢?分析一下:

我之前的常有習慣:遇到問題,先看看官網,不行的話,就百度和谷歌一下,然後再不行,我就問問專案組的夥伴。這種方式,本身沒有什麼大問題。但是,今天學習到了大哥的一種思維方式:spring官網提供了一個解決方案,由此推導Java EE官網也可能提供一個官方解決方案。就這種由此及彼的推導方式,聯絡思維,在之前,我還是比較弱的。今後,要好好實踐運用!