前後端分離的學習與總結

爲什麼需要前後端分離?
因爲傳統開發的後臺開發中,後臺工作者需要設計MVC三層,前後端都要懂一點,有點麻煩。
先看一下傳統開發流程:
在這裏插入圖片描述在這裏插入圖片描述
弊端:耦合度高,一旦出錯不易找錯
耦合度高導致維護性差,開發效率也低
擴展性差,無法兼容其他終端例如app
調試效率低
前後端分離後開發流程
在這裏插入圖片描述
觀察可以發現:
前後端分離後,後臺需要提供一個接口文檔,開發相應的接口。
那接口文檔是個什麼東東呢?

接口文檔:告訴前端:接口地址,參數是什麼,分別是什麼類型,返回值格式,每個key表示什麼含義,下面有例子。

在這裏插入圖片描述

那麼什麼HTTP服務器(靜態資源服務器)?它和tomcat服務器的區別是什麼呢?
HTTP服務器就是隻要能響應HTTP請求即可;
tomcat是servlet容器,可以處理HTTP請求,也能解析執行JSP+servlet

對比我們之前編寫的整個項目結構和部署環境而言,有以下區別:
在這裏插入圖片描述
簡言之,就是在傳統開發上增加了一個服務器處理靜態資源,將View和Controller層放到了前端,後臺僅需處理數據存取相關及業務邏輯相關

前端:負責View和Controller層
後端:只負責Model層,業務處理/數據等。

前後端分離的優缺點

優點:

關注點分離,視圖層和控制層邏輯移到了前端,後端更注重業務邏輯和系統構架

耦合大大降低,開發效率和維護效率都得到提高

錯誤友好,後臺錯誤不影響前臺界面展示

對於開發者,前後端不再需要過多的涉及彼此的開發語言

缺點:

前端開發者壓力更大,需要關注Controller層

增加靜態服務器後,系統結構更復雜

更多的HTTP請求,在移動端運行效率差

邏輯靠近前端,不同平臺需針對性重複實現,(安卓iOS+web)

SEO優化無力,爬蟲大多不支持ajax

爬蟲一般只爬靜態頁面 xx.html
SEO(搜索引擎優化)搜索引擎本質上就是一個爬蟲,seo優化本質就是對爬蟲友好。

重新定義前後端

前後端分離 如何劃分前端和後端?根據職責劃分
前端負責V+C,後端負責 M和Service
前後端分離後,請求次數會變多
在這裏插入圖片描述

前後端分離頁面執行流程(針對瀏覽器)

Controller層中會使用流程控制來完成數據校驗,數據解析,頁面的跳轉等動作,那麼如何完成呢,這就需要使用到JavaScript了在這裏插入圖片描述
注意:如果前端是其他的例如iOS,安卓,則無需請求靜態頁面,頁面的繪製是由系統原始語言實現的,只需要向後臺請求json數據即可

那麼一個前後端分離的項目,前端是如何完成最終的數據展示呢?上面已經提到,就是json

json
格式簡單
解析方便,跨平臺
輕量級
內容爲字符串
Ajax
Ajax是客戶端的一種請求方式,用於異步的向服務器發送HTTP請求並獲取響應數據。

異步的好處在於,請求期間瀏覽器不會被卡死,可以正常響應用戶操作

而常見的表單提交,和直接打開指定地址,都是同步的。

再次說一下接口文檔:告訴前端:接口地址,參數是什麼,分別是什麼類型,返回值格式,每個key表示什麼含義
下面書寫一個簡單的前後端分離
準備一個接口

package com.cx;

import java.io.IOException;

@javax.servlet.annotation.WebServlet(name = "jsonServlet",urlPatterns = "/jsonServlet")
public class jsonServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        //告訴客戶端,返回值的類型是json
        response.setContentType("application/json;charset=utf-8");
        //返回的具體數據
       response.getWriter().println("{\"name\":\"22我\",\"age\":18}");
    }
}

編寫靜態頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery-2.1.0.js"></script>
</head>
<body>
    <h1>我是主頁</h1>
    <script>
        $.ajax({
            //請求的地址
            url:"http://localhost:8080/qianHouDFL/jsonServlet",
            //如果請求成功執行的代碼
            success:function (data) {
                console.log(data);//data是服務器返回的數據
                //將返回數據做成一個標籤插入到頁面中顯示
                document.body.insertAdjacentHTML("beforeend","<h1>%</h1>".replace("%",data.name));
                document.body.insertAdjacentHTML("beforeend","<h1>%</h1>".replace("%",data.age));
            },
            //如果請求失敗執行的代碼
            error:function (err) {
                console.log(err);
            }
        });
    </script>
    哈哈哈
</body>
</html>

根據訪問路徑http://localhost:8080/qianHouDFL/mine.html得到運行結果
在這裏插入圖片描述
如果將.html拉到外面運行,例如HBuilder(別忘了導入依賴)則會發現頁面上沒有顯示服務器返回的結果….

前後端分離之跨域問題
在這裏插入圖片描述
打開瀏覽器檢查頁面會發現沒有輸出服務器返回的消息而是,出現了一個錯誤信息,這就是前後端分離最常見的跨域問題

跨域就是一個頁面的腳本訪問了一個不屬於當前服務器的資源

跨域是一個動詞,描述的是瀏覽器在解析js時發現js代碼請求了一個不屬於當前服務器的資源,此時就是跨域訪問

默認情況下,跨域訪問是不被允許的,其本質是因爲瀏覽器遵循了一個安全機制叫做同源策略

怎麼判斷是否同源?
ip(主機地址或域名) 端口號 請求協議

同源限制:
無法讀取非同源網頁的 Cookie、LocalStorage 和 IndexedDB

無法向非同源地址發送 AJAX 請求

什麼時候產生跨域問題:
瀏覽器在解析執行一個網頁時,如果頁面中的js代碼請求了另一個非同源的資源,則會產跨域問題

而瀏覽器直接跳轉另一個非同源的地址時不會有跨域問題

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

在響應頭中添加一個字段,告訴瀏覽器,某個服務器是可信的

package com.cx;

import java.io.IOException;

/**
 *
 */
@javax.servlet.annotation.WebServlet(name = "jsonServlet",urlPatterns = "/jsonServlet")
public class jsonServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        //告訴客戶端,返回值的類型是json
        response.setContentType("application/json;charset=utf-8");
        //解決跨域問題,在響應頭中明確指出,對方是可信的
        //*表示 允許所有來源的跨域訪問 (測試時用,正式部署需要指定爲靜態資源服務器地址)
        response.setHeader("Access-Control-Allow-Origin","*");
        //返回的具體數據
       response.getWriter().println("{\"name\":\"22我\",\"age\":18}");
    }
}

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

其他相關設置

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

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