前後端分離之後,請求跨域無法傳遞cookie的問題,最近在做公司一個小項目時遇到坑,記錄一下下

前後端分離之後,請求跨域無法傳遞cookie的問題,最近在做公司一個小項目時遇到坑,記錄一下下

前言

那一天是我畢業後工作生涯的第30天,第一次接觸前後端分離開發,我感覺好像,慢慢領悟到了前後端分離開發的真諦:或許大概可能也許是前後端甩鍋開發

場景一
前臺瘋狂的點擊頁面,發送請求,但是後臺服務器總是沒有迴應,後臺接口雖打了斷點,但是根本進不到斷點處。。。

前端:我請求發過去了,數據格式也是對的,你接口文檔就是那樣寫的,我按照接口文檔要求寫的,你服務器怎麼了,你接口寫的對嗎,巴拉巴拉。。。。

後臺:我接口文檔寫的很對欸,我這邊postman測試可以的,我測試通過了才寫的文檔欸,你那邊什麼情況啊,你發送的請求對嗎,巴拉巴拉。。。

場景二
前臺登陸的時候,驗證碼一直校驗不通過

前端:我輸入的驗證碼,就是圖片中的驗證碼,爲什麼你後臺一直校驗不通過啊,怎麼肥四啊,你後臺接口寫的對嗎,邏輯判斷的對嗎,巴拉巴拉。。。。

後臺:肯定對啊,我這邊我自己用postman已經測試通過了,你那邊怎麼搞的,我後臺都獲取不到你的 session 欸,巴拉巴拉。。。

跨域問題

場景一
就是典型的跨域問題,在前後端分離開發的時候,由於前後臺代碼不在一臺服務器上了,前端頁面服務器想要訪問後臺接口的時候,由於瀏覽器的 同源策略,會拒絕掉這些訪問,導致後臺根本收不到這些請求;

後臺需要配置下;

  /**
   * 處理跨域問題
   */
@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 1允許服務端訪問
        corsConfiguration.addAllowedOrigin("*");
        // 1.1允許本地訪問
        corsConfiguration.addAllowedOrigin("http://localhost:8032");
        // 2允許任何頭
        corsConfiguration.addAllowedHeader("*");
        // 3允許任何方法(post、get等)
        corsConfiguration.addAllowedMethod("*");
        // 4 允許withCredentials報文頭
        corsConfiguration.setAllowCredentials(true);
        return corsConfiguration;
    }
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }
}

最簡單粗暴的,來自任何源的請求都接收;

cookie問題

跨域訪問的時候,瀏覽器默認是不帶cookie去的,這樣導致每次後臺都產生根據請求產生新的session,驗證碼值保存在各自的session裏面,當然也就永遠的檢驗不通過了!

前臺在發送 Ajax 請求的時候,告訴瀏覽器允許跨域帶 cookie ,(這是坑請注意。。。)寫上如下;

$.ajax({
	type: "POST",
	url: serverPath + "/api/v1/login",
	contentType: 'application/x-www-form-urlencoded;charset=utf-8',
	data: {username:$("#username").val(), password:$("#password").val(), rememberMe},
	dataType: "json",
	xhrFields: {
		withCredentials: true  //攜帶跨域cookie
	},
	success: function(data){
		if(data.code == 200){
			layer.msg(data.msg);
			window.location.href="index.html";
		}else{
			layer.msg(data.msg);
		}
	},	
})

攔截器導致的跨域問題

上面的問題都解決以後,最後給系統加上攔截器。跨域問題又來了。

我們需要在攔截器裏面放行 options 方法,此方法是瀏覽器發出來的探測方法,探測目標主機是否允許跨域,結果在探測的時候,被攔截器攔截了,送出去的偵察兵音信全無,瀏覽器就不會向目標主機發送請求了,發出一個 cros 跨域錯誤


public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

    /**
     * 在訪問controller前判斷是否登錄,返回json,不進行重定向。
     * @param request
     * @param response
     * @return true-繼續往下執行,false-該filter過濾器已經處理,不繼續執行其他過濾器
     * @throws Exception
     */

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (request instanceof HttpServletRequest) {
            if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
                return true;
            }
        }
        return super.isAccessAllowed(request, response, mappedValue);
    }
}

後記

多年以後,或許我說的最多的話就是:

  • 我這邊能用
  • 在我這是好使的
  • postman測試可以通過
  • 你沒清緩存吧
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章