天天看點

前後端分離之跨域問題

跨域問題

前後端分離之跨域問題

打開浏覽器檢查頁面會發現沒有輸出伺服器傳回的消息而是,出現了一個錯誤資訊,這就是前後端分離最常見的跨域問題

問題原因

這是因為浏覽器都采用了同源政策,即不允許通路不屬于本伺服器的資源。

同源政策

同源政策(Same origin policy)是一種約定,它是浏覽器最核心也最基本的安全功能,如果缺少了同源政策,則浏覽器的正常功能可能會受到影響。可以說Web是建構在同源政策基礎之上的,浏覽器隻是針對同源政策的一種實作。

同源政策是浏覽器的行為,是為了保護本地資料不被JavaScript代碼擷取回來的資料污染,浏覽器會先發送OPTION請求進行預檢查,判斷伺服器是否允許跨域,如果允許才發送真正的請求,否則抛出異常。

簡單的說:

同源政策是浏覽器的核心安全機制,其不允許在頁面中解析執行來自其他伺服器資料

同源限制

1、不允許通路非同源網頁的Cookie、LocalStorage 和 IndexedDB。

      2、不允許向非同源位址發送ajax請求。
           

如何判斷跨域

當請求的url的協定,域名,端口号三者中任意一個與目前url不同,即為跨域

什麼時候會産生跨域問題

當浏覽器在解析資料時,頁面中js代碼請求了非同源的資源,則會産生跨域問題,當浏覽器直接跳轉到另一個非同源頁面,不會發生跨域問題

跨域解決方法

需要設定浏覽器允許解析跨域請求的資料,但是這個設定必須放在伺服器端,由伺服器端來判斷對方是否可信任

設定接口:

在需要通路的接口的響應頭中添加一個字段,告訴浏覽器,某個伺服器是可信的

其值可以是某個或多個指定的域名,也可以是*表示信任所有位址

//指定允許其他域名通路
'Access-Control-Allow-Origin:http://XXX.XXX.XXX'//一般用法(*,指定域,動态設定),注意*不允許攜帶認證頭和cookies
//預檢查間隔時間
'Access-Control-Max-Age: 1800'
//允許的請求類型
'Access-Control-Allow-Methods:GET,POST,PUT,POST'
//列出必須攜帶的字段
'Access-Control-Allow-Headers:x-requested-with,content-type'
           

過濾器設定

通過過濾器進行整體設計:

@WebFilter(filterName = "HTTPFilter",urlPatterns = "/*")
public class HTTPFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletResponse response = (HttpServletResponse)resp;
        //允許通路的方法:POST,GET
        response.setHeader("Access-Control-Allow-Methods","POST,GET");
        //設定響應類型為json資料
        response.setContentType("application/json;charset=utf-8");
        //允許http://127.0.0.1:8848跨域通路,寫死了一般不這樣寫
        //response.setHeader("Access-Control-Allow-Origin","http://127.0.0.1:8848");
        //動态設定
        ArrayList<String> hosts = new ArrayList<String>();
        hosts.add("http://127.0.0.1:8848");
        HttpServletRequest request = (HttpServletRequest)req;
        if (hosts.contains((request.getHeader("Origin")))){
            response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
        }
        chain.doFilter(req, resp);
    }
}
           

cookie跨域

預設情況下cookie是不允許跨域傳輸的.可以通過以下方式來解決

第一步

浏覽器端設定允許cookie跨域

前後端分離之跨域問題

第二步

伺服器端在響應中添加字段,說明允許cookie跨域

該值隻能是true,為false無效,預設為false

跨域問題的解決方案補充

跨域問題除了通過設定header的方式來允許浏覽器進行跨域通路外,也可以通過反向代理來解決跨域問題

代理伺服器

當我們使用了代理後,可以利用代理伺服器來完成請求轉發,即所有請求,都會先發送到代理伺服器,代理伺服器再和真正的伺服器進行互動,而這個互動過程是不會産生有跨域問題産生的

ngin 和node.js等都可以作為代理伺服器

在開發階段通常是使用node+vue來完成環境搭建 上線則使用nginx

強調

因為跨域問題是因為同源政策,而同源政策隻是針對浏覽器的一個政策,即在使用除浏覽器之外的其他任何用戶端請求都不會産生跨域問題

連結:前後端分離狀态保持問題之JWT