主頁 > 企業開發 > vue koa2 mongodb 從零開始做個人博客(二) 登錄注冊功能后端部分

vue koa2 mongodb 從零開始做個人博客(二) 登錄注冊功能后端部分

2020-10-04 16:01:12 企業開發

0.效果演示

插入視頻插不進來,就很煩,可以出門右拐去優酷看下(點我!), 

1.后端搭建

1.1專案結構

首先看一下后端的server目錄

 挨個解釋一下

  • 首先dbs檔案夾顧名思義,操作資料庫的,modules就是操作資料庫的mongoose模型,
  • config.js是為了方便修改資料庫資料,
  • interface就是介面檔案夾,utils就是工具的意思唄,介面需要用到的axios和賬號集權的passport都在這里修改(passport是啥待會兒再細說),
  • 和utils同級的就是users.js 就是user介面的路由,具體的邏輯就在這個檔案里
  • index.js和dbs,interface檔案夾同級,是整個server目錄的入口檔案,

 

1.2后端配置

首先看一下config.js,直接放代碼,

 1 // 匯出相應的配置,然后可以方便的用下面的資料,改的話也比較方便修改,
 2 export default {
 3   //dbs 表示需要連接的服務器
 4   dbs: "mongodb://127.0.0.1:27017/myblog2",
 5   //redis物件是提供redis的資訊
 6   redis: {
 7     get host() {
 8       return "127.0.0.1";
 9     },
10     get port() {
11       return 6379;
12     }
13   },
14   // smtp物件是利用郵箱來發送驗證碼的
15     smtp: {
16     get host() {
17       return "stmp.qq.com";
18     },
19     get user() {
20       return "[email protected]";
21     },
22     // 這個pass碼是qq郵箱給提供的,下面是隨機打的不是真實的,
23     get pass() {
24       return "pfpeqwddadadasdaf";
25     },
26     // 制造一個隨機的驗證碼
27     get code() {
28       return () => {
29         return Math.random()
30           .toString(16)
31           .slice(2, 6)
32           .toUpperCase();
33       };
34     },
35     // 創建一個時間,時間就是發送郵箱的時間,
36     get expire() {
37       return () => {
38         return new Date().getTime() + 60 * 60 * 1000;
39       };
40     }
41   }
42 };

針對于smtp協議,就是你可以利用它來發送驗證碼的,至于如何獲取qq郵箱的pass碼?

↓首先打開郵箱點擊設定:

↓點擊上方navbar的賬號按鈕

↓滑到下面,找到smtp選項 

 

1.3創建資料模型

鋪墊性的東西太多,建議都學完再來看,

1、mongodb和mongoose不詳細展開講了,mongodb可參考我之前寫的入門教程(點我!

2、mongoose大體流程是引入,創建shcema ,創建model,然后進行操作,詳情進入官網(點我!),針對于這個順序先不引入,引入是index.js里的,現在先講創建schema和創建model這個部分的,

3、用了些async await和解構賦值的語法,如果有不太理解的可以自動跳轉去學習一下新版本的js,推薦阮一峰的《ECMAScript 6 入門教程》(直接點書名!)

 

不多說,直接放代碼:

 1 // server/dbs/modules/user.js
 2 // 匯入Monogoose
 3 import mongoose from "mongoose";
 4 // 創建schema
 5 const Schema = mongoose.Schema;
 6 // 創建userSchema
 7 const UserSchema = new Schema({
 8   username: {
 9     type: String,
10     unique: true,
11     require: true
12   },
13   password: {
14     type: String,
15     require: true
16   },
17   email: {
18     type: String,
19     require: true
20   }
21 });
22 // 匯出user模型
23 export default mongoose.model("User", UserSchema);

現在登錄注冊需要存入庫中的只需要這些,驗證方面的快取資料統一存到redis里,reids的邏輯統一在users的介面里講,

 

1.4創建users介面 

可能大家沒注意到我沒說utils里的內容,axios和passport.js ,因為現在時機未到,

現在先配置一下user介面,支起來個架子,然后再談邏輯

// koa-router必引的,不多解釋
import Router from "koa-router";
// 發送驗證碼用redis,因為可能需求量會很大,redis效率較高
import Redis from "koa-redis";
// 用nodeMailer插件來發送郵件,
import nodeMailer from "nodemailer";
// USer模型,來操作mongodb
import User from "../dbs/modules/users";
// 用來發郵件的配置引數
import Email from "../dbs/config";
// axios來請求資料
import axios from "./utils/axios";
//來引入passprot中間件
import Passport from "./utils/passport";

// 創建一個路由,他的最開始用/users
let router = new Router({ prefix: "/users" });

// 創建一個redis的倉庫,
let Store = new Redis().client;

// 匯出router
export default router;

 redis的邏輯是引入koa-redis插件,然后新建store物件,然后我們針對store物件進行相應的操作,詳細介紹請去npm看(點我!

 

1.4.1 注冊驗證碼介面

首先第一個任務那就是注冊,注冊的邏輯是填寫郵箱和用戶名,確定密碼,然后發送驗證碼郵件進行驗證,

那么首先配置的就是發送驗證碼的路由,因為都是線性的代碼,所以直接放代碼,代碼如下:

 1 // 發送驗證碼
 2 router.post("/verify", async ctx => {
 3   //獲取username
 4   let username = ctx.request.body.username;
 5 
 6   //可以不看6-16行,看到結尾再回來看,
 7   //獲得驗證碼的有效時間
 8   const saveExpire = await Store.hget(`nodemail:${username}`, "expire");
 9   //如果驗證碼的有效時間太短,就不能再發次發送,
10   if (saveExpire && new Date().getTime() - saveExpire < 0) {
11     ctx.body = {
12       code: -1,
13       msg: "驗證請求過于頻繁,1分鐘內1次"
14     };
15     return false;
16   }
17   //然后用nodeMailer創建一個transport
18   let transporter = nodeMailer.createTransport({
19     // server名稱
20     service: "qq",
21     // user的名稱和他的pass
22     auth: {
23       user: Email.smtp.user,
24       pass: Email.smtp.pass
25     }
26   });
27   //獲取到驗證碼和時間,還有用戶輸入的郵箱和用戶名
28   let ko = {
29     code: Email.smtp.code(),
30     expire: Email.smtp.expire(),
31     email: ctx.request.body.email,
32     user: ctx.request.body.username
33   };
34   // 郵件的組態檔
35   let mailOptions = {
36     from: `" 博客注冊認證郵件" <${Email.smtp.user}>`,
37     to: ko.email,
38     subject: "王梓瑞的博客注冊驗證碼",
39     html: `驗證碼是${ko.code},請盡快完成注冊!`
40   };
41   await transporter.sendMail(mailOptions, (error, info) => {
42     if (error) {
43       return console.log(error);
44     } else {
45       // 當郵件發送成功了,就將資料保存起來,以后可以拿來用,
46       Store.hmset(
47         `nodemail:${ko.user}`,
48         "code",
49         ko.code,
50         "expire",
51         ko.expire,
52         "email",
53         ko.email
54       );
55     }
56   });
57   ctx.body = {
58     code: 0,
59     msg: "驗證碼已發送,可能會有延時,有效期1分鐘"
60   };
61 });

 

1.4.2注冊介面 

等發完驗證碼 ,我們就可以繼續進行注冊操作,

同樣直接放代碼,很好理解,

router.post("/signup", async ctx => {
  // 先獲取表單里的資訊,這么寫是es6的解構賦值語法
  const { username, password, email, code } = ctx.request.body;
  if (code) {
    const saveCode = Store.hget(`nodemail:${username}`, "code");
    const saveExpire = Store.hget(`nodemail:${username}`, "expire");

    if (saveCode == code) {
      if (new Date().getTime() - saveExpire > 0) {
        ctx.body = {
          code: -1,
          msg: "驗證碼已過期,請重新嘗試"
        };
        return false;
      }
    } else {
      ctx.body = {
        code: -1,
        msg: "請填寫正確的驗證碼"
      };
    }
  } else {
    ctx.body = {
      code: -1,
      msg: "未輸入驗證碼"
    };
  }
let user
= await User.find({ username }); if (user.length) { ctx.body = { code: -1, msg: "已被注冊" }; return; } let nuser = await User.create({ username, password, email }); console.log(nuser); if (nuser) { ctx.body = { code: 0, msg: "注冊成功" }; } else { ctx.body = { code: -1, msg: "注冊失敗" }; } });

 

 

1.4.3 登錄介面

進行到這里就涉及到了passport,因為登陸的狀態是需要集中去進行管理的,那么就涉及到Passport這個插件,如果需要快速上手的話,可以看看這篇簡書(點我!

我這里直接就是講實戰了,不多說了,可以參考著上面的簡書加上我的代碼自行理解,

 1 // server/interface/utils/passport.js
 2 // 引入 passprot ,然后引入本地策略,就是驗證用戶是否成立,最后引入操作模型,
 3 import passport from "koa-passport";
 4 import LocalStrategy from "passport-local";
 5 import UserModel from "../../dbs/modules/users";
 6 
 7 // passport 加載策略中間件,然后通過新建location物件在里面進行對用戶的鑒定,
 8 passport.use(
 9   //創建新的策略,然后三個引數分別是 用戶名密碼和回呼
10   new LocalStrategy(async function(username, password, done) {
11     //此處用where是表示搜索的時候引數是一個物件
12     let where = {
13       username
14     };
15     // 用user的Mongoose的模型來搜索user在資料庫中的記錄,用res來接收
16     const res = await UserModel.findOne(where);
17     // 判斷res是否存在, 不存在就用策略的回呼函式done回傳一個用戶不存在的錯誤資訊,
18     if (res != null) {
19       // 如果資料庫里的Password和輸入的password吻合,就回傳一個res
20       if (res.password === password) {
21         return done(null, res);
22       } else {
23         // 不吻合就回傳一個密碼錯誤,
24         return done(null, false, "密碼錯誤");
25       }
26     } else {
27       return done(null, false, "用戶不存在");
28     }
29   })
30 );
31 
32 // 序列化和反序列化,沒什么大事,
33 passport.serializeUser(function(user, done) {
34   done(null, user);
35 });
36 
37 passport.deserializeUser(function(user, done) {
38   return done(null, user);
39 });
40 
41 // 匯出passport集權控制中間件,
42 export default passport;

 

再放user.js介面里的代碼

 1 router.post("/signin", async (ctx, next) => {
 2   return Passport.authenticate("local", (err, user, info, status) => {
 3     if (err) {
 4       ctx.body = {
 5         code: -1,
 6         msg: err
 7       };
 8     } else {
 9       if (user) {
10         ctx.body = {
11           code: 0,
12           msg: "登錄成功",
13           user
14         };
15         return ctx.login(user);
16       } else {
17         ctx.body = {
18           code: 1,
19           msg: info
20         };
21       }
22     }
23   })(ctx, next);
24 });

 

這里可能有人會有疑問,就說我的介面都沒有獲取到ctx里面的username和password資料,怎么直接就return了passport的物件呢?

問題就在必須在index.js讓koa2物件使用bodyParser的中間件,代碼如下:

 // bodyParser中的extendTypes必須要加,要不然passport就無法決議username和passport
  app.use(
    bodyParser({
      extendTypes: ["json", "form", "text"]
    })
  );

 

然后就可以決議到登錄過來的username和passport了,

 

1.4.4 退出和查詢用戶介面

直接放代碼,沒有難度

 1 router.get("/getUser", async ctx => {
 2   if (ctx.isAuthenticated()) {
 3     const { username, email } = ctx.session.passport.user;
 4     ctx.body = {
 5       user: username,
 6       email
 7     };
 8   } else {
 9     ctx.body = {
10       user: "",
11       email: ""
12     };
13   }
14 });

 

退出登錄

 1 router.get("/exit", async (ctx, next) => {
 2   await ctx.logout();
 3   if (!ctx.isAuthenticated()) {
 4     ctx.body = {
 5       code: 0
 6     };
 7   } else {
 8     ctx.body = {
 9       code: -1
10     };
11   }
12 });

 

如果你想獲取用戶資料的話還有第二種方法,從session獲取,session是什么?大家自行百度下,簡單來說就是服務端的cookie,

然后運用vuex 配合 nuxt.js的nuxtServerInit方法,這個又需要理解vuex和nuxtServerInit,這個放上鏈接,vuexnuxtServerInit

專案結構

 

 

如果用vue-cli會有modules檔案夾來放模型的,但是nuxt.js直接都放在平級了,詳情可參照nuxt.js檔案,(點我!)

 

同樣直接放代碼吧,

 1 //store/user.js
 2 const state = () => ({
 3   user: ""
 4 });
 5 const mutations = {
 6   setUser(state, param) {
 7     state.user = param;
 8   }
 9 };
10 const actions = {
11   setUser: ({ commit }, param) => {
12     commit("setUser", param);
13   }
14 };
15 
16 export default { state, mutations, actions };
 1 //store/index.js
 2 const actions = {
 3   async nuxtServerInit({ commit }, { req }) {
 4     if (req.user) {
 5       commit("user/setUser", req.user.username);
 6     }
 7   }
 8 };
 9 
10 export { actions };

 

 然后我們就可以在頁面的任何位置呼叫 $store.state.user.user 即可獲得用戶的用戶名了,可以省去異步獲取的操作,

 

1.5 index.js檔案

直接放代碼,之前解釋的都解釋過了,這個就是一個啟動后端的檔案

 1 // server/index.js
 2 const Koa = require("koa");
 3 const consola = require("consola");
 4 const { Nuxt, Builder } = require("nuxt");
 5 
 6 import bodyParser from "koa-bodyparser"; // 這個一開始就要加,不加的話決議不出來request.body,post請求就白給,
 7 import json from "koa-json";
 8 import mongoose from "mongoose";
 9 import dbConfig from "./dbs/config";
10 import Redis from "koa-redis";
11 import session from "koa-generic-session";
12 import users from "./interface/users";
13 import passport from "./interface/utils/passport";
14 
15 const app = new Koa();
16 
17 // Import and Set Nuxt.js options
18 const config = require("../nuxt.config.js");
19 config.dev = app.env !== "production";
20 
21 async function start() {
22   // Instantiate nuxt.js
23   const nuxt = new Nuxt(config);
24 
25   const {
26     host = process.env.HOST || "127.0.0.1",
27     port = process.env.PORT || 3000
28   } = nuxt.options.server;
29 
30   //這個是加密用的
31   app.keys = ["my", "keyskeys"];
32   //是否設定代理
33   app.proxy = true;
34   //session的前綴
35   app.use(session({ key: "my", prefix: "my:uid", store: new Redis() }));
36   //mongoose鏈接Mongodb
37   mongoose.connect(dbConfig.dbs, {
38     useNewUrlParser: true
39   });
40   //初始化passport
41   app.use(passport.initialize());
42   //讓passport使用session
43   app.use(passport.session());
44 
45   // Build in development
46   if (config.dev) {
47     const builder = new Builder(nuxt);
48     await builder.build();
49   } else {
50     await nuxt.ready();
51   }
52   //決議json用的中間件
53   app.use(json());
54   // bodyParser中的extendTypes必須要加,要不然passport就無法決議username和passport
55   app.use(
56     bodyParser({
57       extendTypes: ["json", "form", "text"]
58     })
59   );
60   // 加載路由中間件
61   app.use(users.routes()).use(users.allowedMethods());
62 
63   app.use(ctx => {
64     ctx.status = 200;
65     ctx.respond = false; // Bypass Koa's built-in response handling
66     ctx.req.ctx = ctx; // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
67     nuxt.render(ctx.req, ctx.res);
68   });
69 
70   app.listen(port, host);
71   consola.ready({
72     message: `Server listening on http://${host}:${port}`,
73     badge: true
74   });
75 }
76 
77 start();

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/154864.html

標籤:JavaScript

上一篇:一起學Vue之事件處理

下一篇:【JavaScript Weekly】#471 — JANUARY 17, 2020

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more