上篇文章書寫了前後端分離,在此再敘述一下
前後端分離的劃分時按照職責劃分
前端: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'