摘要:簡稱是公司內(nèi)部的混合語言數(shù)據(jù)標(biāo)準(zhǔn),他們用于系統(tǒng)和持續(xù)數(shù)據(jù)存儲系統(tǒng)??捎糜谕ㄓ崊f(xié)議數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)平臺無關(guān)可擴展的序列化結(jié)構(gòu)數(shù)據(jù)格式。我們想要的結(jié)果是最終的返回的數(shù)據(jù)。如果當(dāng)前開發(fā)開啟,就回直接返回數(shù)據(jù)。數(shù)據(jù)是與同級的文件。
Protobuf
Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內(nèi)部的混合語言數(shù)據(jù)標(biāo)準(zhǔn),他們用于 RPC 系統(tǒng)和持續(xù)數(shù)據(jù)存儲系統(tǒng)。
Protocol Buffers 是一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲格式,可以用于結(jié)構(gòu)化數(shù)據(jù)串行化,或者說序列化。它很適合做數(shù)據(jù)存儲或 RPC 數(shù)據(jù)交換格式??捎糜谕ㄓ崊f(xié)議、數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)、平臺無關(guān)、可擴展的序列化結(jié)構(gòu)數(shù)據(jù)格式。為什么要講到它,因為我們后臺的協(xié)議就是用的它。
MockMock也可以叫mock object,模擬對象,在面向?qū)ο蟪绦蛟O(shè)計中,以可控的方式模擬真實對象行為的假對象。前端比較有名的庫是Mock.js。
為什么要mock呢?
1、前后端分離,并行開發(fā),能夠充分利用人力,避免等待。
2、可以豐富測試用例,提前模擬很多的真實場景數(shù)據(jù),而不必等到線上環(huán)境才發(fā)現(xiàn)問題。
但Mock.js有個問題:學(xué)習(xí)和配置成本高。
// 配置 Mock 路徑 require.config({ paths: { mock: "http://mockjs.com/dist/mock" } }) // 加載 Mock require(["mock"], function(Mock){ // 使用 Mock var data = Mock.mock({ "list|1-10": [{ "id|+1": 1 }] }) // 輸出結(jié)果 document.body.innerHTML += "" + JSON.stringify(data, null, 4) + "" }) // ==> { "list": [ { "id": 1 }, { "id": 2 }, { "id": 3 } ] }
用它之前必須要先配置一個Ajax的請求路徑,然后根據(jù)后臺的協(xié)議,學(xué)習(xí)mock的語法,才能模擬出list這個數(shù)組。所以這里存在著兩個問題:
1、配置成本和語法學(xué)習(xí)成本
2、后臺協(xié)議轉(zhuǎn)換為mock語法
很多時候,等到我們開發(fā)完業(yè)務(wù)邏輯,已經(jīng)沒有多少耐心來寫這個mock邏輯,簡單的協(xié)議還好,如果涉及到很復(fù)雜的,寫這個mock的邏輯就更加不愿意。
為了幫前端同學(xué)偷個懶,有必要把這個過程給省了。
Protobuf轉(zhuǎn)換為JSONgit上已經(jīng)有針對Protobuf開源的js接口:https://github.com/dcodeIO/pr...。因為構(gòu)建工具我們使用的是gulp,同樣的也有個對應(yīng)的插件:gulp-protobufjs,但是沒法拿來就用。
首頁我們來看下這個gulp-protobufjs插件所做的事情
var gulp = require("gulp"); var gulpprotobuf = require("gulp-protobufjs"); gulp.task("default", function () { return gulp.src("file.proto") .pipe(gulpprotobuf()) .pipe(gulp.dest("out/")); });
讀取proto文件,然后生成一個文件,文件類型可以自定義。
如果產(chǎn)出的是.js文件,那么結(jié)果是commonjs模塊文件:
module.exports = require("protobufjs").newBuilder({})["import"]({ "package": "mmgameweappwap", "syntax": "proto2", "messages": [ { "name": "User", "syntax": "proto2", "fields": [ { ……
如果是.json文件:
{ "package": "mmgameweappwap", "syntax": "proto2", "messages": [ { "name": "UserItem", "syntax": "proto2", "fields": [ { "rule": "required", "type": "string", "name": "user_id", "id": 1 }, { "rule": "optional", "type": "string", "name": "head_img_url", "id": 2 }, { "rule": "optional", "type": "string", "name": "nick_name", "id": 3 } ] }, ……
很顯然,這不是我們想要的最終結(jié)果。我們想要的結(jié)果是最終的ajax返回的數(shù)據(jù)。當(dāng)然有了協(xié)議的json結(jié)構(gòu),字段類型、字段名也都有了,剩下的事情就只需根據(jù)他們mock一些數(shù)據(jù)。這個json文件可以理解為對接口的一個描述文件。
pb協(xié)議的rule常見的有以下幾種:
optional:可選
required:必須
repeated:數(shù)組
數(shù)據(jù)類型,有以下幾種最基本的類型,基本都可以映射為js常用的數(shù)據(jù)類型。
例子在解析pb文件的時候,后臺CGI接口名會被定義為message。
package mmgameweappwap; message GetDiceGameRoomRequest { required string room_id = 1; } message GetDiceGameRoomResponse { required int32 errcode = 1; required string errmsg = 2; optional OkResult data = 3; message OkResult { repeated UserDiceItem user_dice_list = 1; required uint32 room_close_remain_second = 2; required bool room_closed = 3; } }
package 可以理解為模塊,上文我們定義了一個mmgameweappwap模塊。
GetDiceGameRoomRequest:請求的message
GetDiceGameRoomResponse:返回的message
GetDiceGameRoom:接口名稱
一個CGI接口在pb協(xié)議中的定義一般會成對的出現(xiàn)。Request、Response是所有接口標(biāo)準(zhǔn)的后綴,以區(qū)別普通的message。依賴這種規(guī)則,就可以把接口解析出來,并且也能夠知道其請求、返回的message。
從上面的pb協(xié)議看,message可以被嵌套,OkResult是屬于GetDiceGameRoomResponse子message。同一個pb文件下,message名可能重復(fù),整個協(xié)議可以看成是一顆樹。如果要找對應(yīng)的message,必須從當(dāng)前節(jié)點的子節(jié)點開始查找,否則可能找錯。
處理的流程比較簡單。如下圖所示:
通過分析知道接口名后,如果前端的請求都是統(tǒng)一的,就可以通過請求接口的代碼模板生成請求代碼。生成對應(yīng)的API.js:
var Promise = require("js/libs/Promise"); var Util = require("js/common/util"); var Mock = require("./mock"); var app = getApp(); var FETCH_URL = "http://xxxxx/gameweappwap/"; module.exports = { getDiceGameRoom: function(data) { return new Promise((resolve, reject) => { if(app.mock){ resolve(Mock.getDiceGameRoom); return; } app.request({ url: FETCH_URL + "getsmobapremadeinfo", data: { room_id: data.room_id, // string }, method: "POST", header: { "content-type": "application/json" }, success: resolve, fail: reject, ……
exports對外的接口就是CGI的接口名:getDiceGameRoom。
request中的roomid就是從pb協(xié)議中解析出來的,后面的注釋標(biāo)注了其類型。這樣一個ajax請求就非常的簡單明了了。開發(fā)者只需要API.getDiceGameRoom調(diào)用即可。如果當(dāng)前app.mock開發(fā)開啟,就回直接返回mock數(shù)據(jù)。mock數(shù)據(jù)是與API.js同級的文件。
這里的數(shù)據(jù)都是調(diào)用mock.js生成的,當(dāng)然我們可以加入一些業(yè)務(wù)的數(shù)據(jù),這樣測試起來更加真實。
運用場景1、前端安全,模擬xss例子。
隨機生成一些xss用例,用于前端頁面的測試。
2、前端UI測試。
在實際工作中,經(jīng)常會遇到文本截斷的問題。UI界面在多行文本的情況下會不會表現(xiàn)正常這個問題,在這種情況下就可以輕易的測試出來,而不需每次叫后臺開發(fā)配合加一些假數(shù)據(jù)。
如下圖,我們可以針對字符串類型的數(shù)據(jù)生成一些長文本。
所有的項目都在統(tǒng)一框架下,每個項目都保持統(tǒng)一的目錄結(jié)構(gòu),只需要自定義一些配置就能初始化項目腳手架,剩下的只需要專注于業(yè)務(wù)開發(fā)。
by addy 原創(chuàng)文章,歡迎轉(zhuǎn)載,但希望全文轉(zhuǎn)載,注明本文地址。http://www.iamaddy.net/2017/0...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/85001.html
摘要:今天這篇文章,我們會介紹幾種常見的方法和其中存在的問題,并提出如何基于請求攔截,快速解決跨域和代理問題的方案。因為沒有修改該請求,只是延遲發(fā)送,這樣就保持了原請求與業(yè)務(wù)服務(wù)器之間的所有鑒權(quán)等相關(guān)信息,由此解決了跨域訪問無法攜帶的問題。 近幾年,隨著 Web 開發(fā)逐漸成熟,前后端分離的架構(gòu)設(shè)計越來越被眾多開發(fā)者認(rèn)可,使得前端和后端可以專注各自的職能,降低溝通成本,提高開發(fā)效率。 在前后端...
摘要:呵呵呵打印出來的是二進制流需要進行化然后給前端。不然的話瀏覽器會自動解析成文字的前端需要進行接受二進制流先引入文件以及插件前端用請求的路由,在回調(diào)函數(shù)里的為后端的返回值。 protobuf介紹 由于網(wǎng)上關(guān)于protobuf的交互的資料比較零散,所以自己整理了一下關(guān)于protobuf前后端交互的資料,以作參考。 Google Protocol Buffers 簡稱 Protobuf,它提...
摘要:不然將根據(jù)屬性名稱進行排序。獲取包裝器獲取包裝器我們可以直接轉(zhuǎn)換模型對象為。所有與對象不能包含值。它們將作為類型進行序列化。我們定義了一個抽象類。使用會獲得最佳性能。許可證許可證庫使用許可證。Wodsoft Protobuf Wrapper內(nèi)容關(guān)于需求安裝用法序列化反序列化字段定義字段排序非空構(gòu)造函數(shù)對象獲取Protobuf包裝器高級支持的屬性類型與Protobuf類型的關(guān)系如何工作性能許可...
閱讀 4996·2021-09-22 14:57
閱讀 622·2019-08-30 15:56
閱讀 2718·2019-08-30 15:53
閱讀 2295·2019-08-29 14:15
閱讀 1738·2019-08-28 17:54
閱讀 610·2019-08-26 13:37
閱讀 3540·2019-08-26 10:57
閱讀 1106·2019-08-26 10:32