前後端分離----跨域篇筆記

上篇文章書寫了前後端分離,在此再敘述一下
前後端分離的劃分時按照職責劃分

前端:VIew(視圖層) Controller(控制層)
後臺:Model(數據操作) Service(業務邏輯)

不同之處:

部署的不同:


傳統:後臺代碼和前端頁面全部部署到一個tomcat中
分離:可以將靜態資源(html,js,css,img...)部署到一個專門的靜態資源服務器,例如nginx

代碼的不同


傳統:接口返回的通常是渲染後的html文檔
分離:接口返回的通常都是json

分離後的優點


降低了耦合度,前後端之間可以儘可能少的涉及彼此的代碼邏輯
分離了關注的,可以讓後臺更加專注的解決業務邏輯數據訪問、系統構架
擴展性提高了,可以搭配不同平臺的前端

前後端分離後會出現最常見的跨域問題

什麼是跨域?

瀏覽器在解析js代碼時,發現js代碼請求了了一個不屬於當前服務器的資源,這時就稱爲跨域訪問
在這裏插入圖片描述
爲什麼會有這個問題出現?
由於瀏覽器遵循同源策略,導致了無法訪問跨域資源。。。。
同源策略是?
同源策略是瀏覽器的核心安全機制,其不允許在頁面中解析執行來自其他服務器數據
同源限制

 不允許訪問非同源網頁的Cookie、LocalStorage 和 IndexedDB。
 不允許向非同源地址發送ajax請求。

怎麼判斷是否同源?
協議,端口,IP
如果三者之一有一個不同,則跨域了

那麼請問移動端存在跨域問題嗎?
no!不存在,同源策略是瀏覽器的策略

跨域問題解決方案

既然禁止跨域問題是瀏覽器的行爲,那麼只需要設置瀏覽器允許解析跨域請求的數據即可,但是這個設置必須放在服務器端,由服務器端來判斷對方是否可信任

在響應頭中添加一個字段,告訴瀏覽器,某個服務器是可信的
即在header中添加允許訪問的地址,在響應頭中明確指出即可

*表示 允許所有來源的跨域訪問 (測試時用,正式部署需要指定爲靜態資源服務器地址)
例如:

       response.setHeader("Access-Control-Allow-Origin","*");

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

一個可以這樣解決,兩個三個呢?更多呢?此時可以使用過濾器,而且不用寫死相應地址。即動態設置跨域

package com.cx.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 *
 */
@WebFilter(urlPatterns = "/*")
public class CROSFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //動態設置 通過代碼獲取origin  判斷要不要允許跨域
        //允許跨域的主機地址列表
        ArrayList<String> hosts = new ArrayList<>();
        hosts.add("http://127.0.0.1:8020");
        hosts.add("http://localhost:8020");
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        //判斷對方是否在允許的範圍
        if (hosts.contains(request.getHeader("Origin"))){
            //從請求中獲取Origin的值
            ((HttpServletResponse)servletResponse).setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

其他相關設置

//指定允許其他域名訪問
//指定允許其他域名訪問
'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'

補充:cookie跨域
默認情況下cookie是不允許跨域傳輸的.可以通過以下方式來解決

第一步
瀏覽器端設置允許cookie跨域

在這裏插入圖片描述

第二步
服務器端在響應中添加字段,說明允許cookie跨域

該值只能是true,爲false無效,默認爲false

#'Access-Control-Allow-Credentials:true'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章