1. 程式人生 > >jquery 跨域 非同步請求 自定義頭部 預檢請求 spring mvc攔截處理 實現token單點登入

jquery 跨域 非同步請求 自定義頭部 預檢請求 spring mvc攔截處理 實現token單點登入

被跨域搞死了,各種奇葩問題。

問題描述:跨域登入,生成token並儲存到redis中,然後返回給客戶端,客戶端每次請求需要將token放到請求頭中傳給服務端,服務端使用過濾器處理跨域攔截,使用攔截器判斷token有效性。問題來了,發來的請求總是獲取不到頭部資訊,也就是取不到token值

解決:

網上說的過濾器需要做的處理都做了,程式碼如下:

		if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
			HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse) res;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,JSONP");
            response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept,Authorization,X-CSRF-TOKEN");
 
            if(request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            	response.setStatus(HttpStatus.OK.value());
            }
        }

        chain.doFilter(req, res);
為什麼單獨處理請求method是options的請求呢,因為非同步請求中,只要你自定義了頭部,預設瀏覽器都會先發送一個預檢請求,看看服務端是否支援他真正的請求,比如我的真正的請求是get的登入請求,所以從瀏覽器裡面可以看到,options真正的請求是get。

做了n多次測試都不好使,各種查資料,才發現問題的所在,上面的程式碼單獨處理了options,瀏覽器只需要對options的返回結果,並不需要你重定向,所以上面的程式碼會報錯302,無法重定向。

後來終於看到一位大哥寫的,無需對options進行重定向,只需要return ; 回去就可以了,經測試真的沒有問題了

最終程式碼如下:

		if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
			HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse) res;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,JSONP");
            response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept,Authorization,X-CSRF-TOKEN");
            
            if(request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            	response.setStatus(HttpStatus.OK.value());
            	return ;
            }
        }
        chain.doFilter(req, res);
當瀏覽器拿到了options的返回結果是200以後,會自動在傳送真正的get請求,這時候的請求直接進入了攔截器,然後你就可以在攔截器裡面獲取自定義頭部的token資訊,並且驗證token的有效性,進行相應的跳轉了。