springboot全局跨域與過濾器跨域

跨域請求

瀏覽器具有同源限制,即完全一致的意思是,域名要相同(www.example.comexample.com不同),協議要相同(httphttps不同),端口號要相同(默認是:80端口,它和:8080就不同)

使用CROS處理跨域

Origin表示本域,也就是瀏覽器當前頁面的域。當JavaScript向外域(如sina.com)發(fā)起請求后,瀏覽器收到響應后,首先檢查Access-Control-Allow-Origin是否包含本域,如果是,則此次跨域請求成功,如果不是,則請求失敗,JavaScript將無法獲取到響應的任何數據。

跨域能否成功,取決于對方服務器是否愿意給你設置一個正確的Access-Control-Allow-Origin,決定權始終在對方手中。

簡單跨域請求

上面這種跨域請求,稱之為“簡單請求”。簡單請求包括GET、HEAD和POST(POST的Content-Type類型
僅限application/x-www-form-urlencodedmultipart/form-datatext/plain),并且不能出現任何自定義頭(例如,X-Custom: 12345),通常能滿足90%的需求。

其他類型的請求

對于PUT、DELETE以及其他類型如application/json的POST請求,在發(fā)送AJAX請求之前,瀏覽器會先發(fā)送一個OPTIONS請求(稱為preflighted請求)到這個URL上,詢問目標服務器是否接受:

OPTIONS /path/to/resource HTTP/1.1
Host: bar.com
Origin: http://my.com
Access-Control-Request-Method: POST

服務器必須響應并明確指出允許的Method:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://my.com
Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS
Access-Control-Max-Age: 86400
Access-Control-Allow-Credentials: true | false // 是否允許攜帶 Cookie

帶cookie的跨域請求

Access-Control-Allow-Credentials 響應頭會使瀏覽器允許在 Ajax 訪問時攜帶 Cookie,但我們仍然需要對 XMLHttpRequest 設置其 withCredentials 參數,才能實現攜帶 Cookie 的目標。

為了安全,標準里不允許 Access-Control-Allow-Origin: *,必須指定明確的、與請求網頁一致的域名。同時,Cookie 依然遵循“同源策略”,只有用目標服務器域名設置的 Cookie 才會上傳,而且使用 document.cookie 也無法讀取目標服務器域名下的 Cookie。

Springboot設置跨域

可以在服務端設置允許跨域訪問,設置如下:

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域
        config.addAllowedOrigin("*");
        //是否發(fā)送Cookie信息
        config.setAllowCredentials(true);
        //放行哪些原始域(請求方式)
        config.addAllowedMethod("*");
        //放行哪些原始域(頭部信息)
        config.addAllowedHeader("*");

        //2.添加映射路徑
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

在實際的實踐中發(fā)現,上述處理方式可以解決大多數情況下的跨域問題,但是當客戶端的請求帶有cookies時,我們就不能使用簡單的通配符*來處理跨域問題,會發(fā)現上述的springboot跨域設置失效,針對這個問題,可以使用過濾器將請求的url進行攔截,重新設置響應頭,就可以完成帶cookie請求跨域的處理。

攔截器處理跨域問題

用filter攔截每次請求,如果攜帶身份信息(Credential)時,獲取到具體的域響應給請求。

public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //根據請求頭設置響應頭
        String allowOrigin = request.getHeader("Origin");
        String allowHeader = request.getHeader("Access-Control-Request-Headers");
        response.setHeader("Access-Control-Allow-Origin", allowOrigin);
        //設置允許帶cookie的請求
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "OPTIONS, POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Headers", allowHeader);
        filterChain.doFilter(servletRequest, servletResponse);
        }
    }

在實際的項目中,全局的跨域設置處理與攔截器可以同時設置,針對帶有cookie的請求,我們可以設置攔截器來進行處理,就可以很好的處理跨域問題。

參考自:https://blog.csdn.net/u014029255/article/details/56842509

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 題目1.什么是同源策略? 同源策略(Same origin Policy): 瀏覽器出于安全方面的考慮,只允許與本...
    FLYSASA閱讀 1,746評論 0 6
  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript實...
    他方l閱讀 1,075評論 0 2
  • CORS 一、CORS內部機制與實現 CORS(Cross-Origin Resource Sharing,跨域資...
    fenerchen閱讀 765評論 0 0
  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript實...
    Yaoxue9閱讀 1,315評論 0 6
  • 從古至今,有農民的種植,才有百姓的生活! 現代人已經越來越少人去種植了,都以賺錢為主,但我們反悟一下,其實農民才是...
    阿玟智吖閱讀 535評論 2 4