日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > HTML >内容正文

HTML

剥开比原看代码09:通过dashboard创建密钥时,前端的数据是如何传到后端的?

發(fā)布時(shí)間:2023/11/29 HTML 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 剥开比原看代码09:通过dashboard创建密钥时,前端的数据是如何传到后端的? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

作者:freewind

比原項(xiàng)目倉(cāng)庫(kù):

Github地址:https://github.com/Bytom/bytom

Gitee地址:https://gitee.com/BytomBlockchain/bytom

在前面一篇文章,我們粗略的研究了一下比原的dashboard是如何做出來(lái)的,但是對(duì)里面提到的各種細(xì)節(jié)功能,并沒(méi)有深入的去研究。那么從本文開(kāi)始,我們將在這一段時(shí)間,分別研究里面提到的每一項(xiàng)功能。

在前一篇文章中,當(dāng)我們第一次在瀏覽器中打開(kāi)dashboard時(shí),因?yàn)檫€沒(méi)有創(chuàng)建過(guò)密鑰,所以比原會(huì)提示我們輸入一些別名和密碼,為我們創(chuàng)建一個(gè)密鑰和相應(yīng)的帳戶。就是下面這張圖所對(duì)應(yīng)的: 那么本文就將研究一下,當(dāng)我們點(diǎn)擊了"Register"按鈕以后,我們?cè)谇岸隧?yè)面上填寫(xiě)的參數(shù),到底是如何一步步的傳到比原的后端的。

跟之前一樣,我們將對(duì)這個(gè)問(wèn)題進(jìn)行細(xì)分,然后各個(gè)擊破:

  • 前端:當(dāng)我們填完表單,點(diǎn)了提交以后,比原在前端是如何發(fā)送數(shù)據(jù)的?
  • 后端:比原的后端是如何接收到數(shù)據(jù)的?
  • 前端:當(dāng)我們填完表單,點(diǎn)了提交以后,數(shù)據(jù)會(huì)發(fā)送到后端的哪個(gè)接口?

    當(dāng)我們點(diǎn)擊了"Register"按鈕,在前端頁(yè)面中,一定會(huì)在某個(gè)地方觸發(fā)一個(gè)向比原節(jié)點(diǎn)webapi接口發(fā)出請(qǐng)求的操作。究竟是訪問(wèn)的哪個(gè)web api?提交的數(shù)據(jù)又是什么樣的呢?讓我們先從前端代碼中尋找一下。

    注意,比原的前端代碼位于另一個(gè)項(xiàng)目倉(cāng)庫(kù)bytom/dashboard中。為了能與我們?cè)诒鞠盗形恼轮惺褂玫谋仍璿1.0.1的代碼相匹配,我找到了dashboard中的v1.0.0的代碼,并且提交到了一個(gè)單獨(dú)的項(xiàng)目中:freewind/bytom-dashboard-v1.0.0。注意該項(xiàng)目代碼未做任何修改,其master分支對(duì)應(yīng)于官方代碼倉(cāng)庫(kù)的v1.0.0分支。之所以要弄一個(gè)單獨(dú)的出來(lái),這是因?yàn)槲覀冊(cè)谖恼轮?#xff0c;每次引用一段代碼的時(shí)候,都會(huì)給出相應(yīng)的github上的鏈接,方便讀者跳過(guò)去查看全貌,使用一個(gè)獨(dú)立項(xiàng)目,會(huì)讓這個(gè)過(guò)程更簡(jiǎn)便一些。

    由于比原的前端頁(yè)面是使用React為主的,所以我猜想在代碼中,也該會(huì)有一個(gè)名為Register的組件,或者某個(gè)表單中有一個(gè)名為Register的按鈕。經(jīng)過(guò)搜索,我們幸運(yùn)的發(fā)現(xiàn)了Register.jsx 這個(gè)組件文件,它正好是我們需要的。

    經(jīng)過(guò)高度簡(jiǎn)化后的代碼如下:

    src/features/app/components/Register/Register.jsx#L9-L148

    class Register extends React.Component {// ...// 4. submitWithErrors(data) {return new Promise((resolve, reject) => {// 5. this.props.registerKey(data).catch((err) => reject({_error: err.message}))})}// ...render() {// ...return (// ...// 3.<form className={styles.form} onSubmit={handleSubmit(this.submitWithErrors)}>// 1.<TextFieldtitle={lang === 'zh' ? '賬戶別名' : 'Account Alias'}placeholder={lang === 'zh' ? '請(qǐng)輸入賬戶別名...' : 'Please enter the account alias...'}fieldProps={accountAlias} /><TextFieldtitle={lang === 'zh' ? '密鑰別名' : 'Key Alias'}placeholder={lang === 'zh' ? '請(qǐng)輸入密鑰別名...' : 'Please enter the key alias...'}fieldProps={keyAlias}/><TextFieldtitle={lang === 'zh' ? '密鑰密碼' : 'Key Password'}placeholder={lang === 'zh' ? '請(qǐng)輸入密鑰密碼...' : 'Please enter the key password...'}fieldProps={password}type='password'/><TextFieldtitle={lang === 'zh' ? '重復(fù)輸入密鑰密碼' : 'Repeat your key password'}placeholder={lang === 'zh' ? '請(qǐng)重復(fù)輸入密鑰密碼...' : 'Please repeat the key password...'}fieldProps={repeatPassword}type='password'/>// 2. <button type='submit' className='btn btn-primary' disabled={submitting}>{lang === 'zh' ? '注冊(cè)' : 'Register'}</button>// ....</form>// ...)} }

    上面的代碼,共有5個(gè)地方需要注意,被我用數(shù)字標(biāo)示出來(lái)了。注意這5個(gè)數(shù)字并不是從上到下標(biāo)注,而是按照我們關(guān)注的順序來(lái)的:

  • 表單上的各個(gè)輸入框,就是我們填寫(xiě)別名和密碼的地方。這里需要關(guān)注的是每個(gè)TextField的fieldProps屬性,它對(duì)應(yīng)我們提交到后臺(tái)的數(shù)據(jù)的name
  • 就是那個(gè)“Register”按鈕了。需要注意的是,它的type是submit,也就是說(shuō),點(diǎn)擊它以后,將會(huì)觸發(fā)所在form的onSubmit方法
  • 回到了form的開(kāi)頭。注意它的onSubmit里面,調(diào)用的是handleSubmit(this.submitWithErrors)。其中的handleSubmit是從該表單所使用的第三方redux-form中傳入的,用來(lái)處理表單提交,我們?cè)谶@里不關(guān)注它,只需要知道我們需要把自己的處理函數(shù)this.submitWithErrors傳給它。而在后者中,我們將會(huì)調(diào)用比原節(jié)點(diǎn)提供的web api
  • 第3步中的this.submitWithErrors最終將走到這里定義的submitWithErrors函數(shù)
  • submitWithErrors將會(huì)發(fā)起一個(gè)異步請(qǐng)求,最終調(diào)用由外部傳進(jìn)來(lái)的registerKey函數(shù)
  • 從這里我們還看不到調(diào)用的是哪個(gè)api,所以我們必須繼續(xù)去尋找registerKey。很快就在同文件中找到了registerKey:

    src/features/app/components/Register/Register.jsx#L176-L180

    (dispatch) => ({registerKey: (token) => dispatch(actions.core.registerKey(token)),// ...})

    它又將會(huì)調(diào)用actions.core.registerKey這個(gè)函數(shù):

    src/features/core/actions.js#L44-L87

    const registerKey = (data) => {return (dispatch) => {// ...// 1.1const keyData = {'alias': data.keyAlias,'password': data.password}// 1.2return chainClient().mockHsm.keys.create(keyData).then((resp) => {// ...// 2.1const accountData = {'root_xpubs':[resp.data.xpub],'quorum':1,'alias': data.accountAlias}// 2.2dispatch({type: 'CREATE_REGISTER_KEY', data})// 2.3chainClient().accounts.create(accountData).then((resp) => {// ...// 2.4if(resp.status === 'success') {dispatch({type: 'CREATE_REGISTER_ACCOUNT', resp})}})// ...})// ...} }

    可以看到,在這個(gè)函數(shù)中,做的事情還是很多的。而且并不是我一開(kāi)始預(yù)料的調(diào)用一次后臺(tái)接口就行了,而是調(diào)用了兩次(分別是創(chuàng)建密鑰和創(chuàng)建帳戶)。下面進(jìn)行分析:

  • 1.1是為了讓后臺(tái)創(chuàng)建密鑰而需要準(zhǔn)備的參數(shù),一個(gè)是alias,一個(gè)是password,它們都是用戶填寫(xiě)的
  • 1.2是調(diào)用后臺(tái)用于創(chuàng)建密鑰的接口,把keyData傳過(guò)去,并且拿到返回的resp后,進(jìn)行后續(xù)的處理
  • 2.1是為了讓后臺(tái)創(chuàng)建帳戶而需要準(zhǔn)備的參數(shù),分別是root_xpubs, quorum和alias,其中root_xpubs是創(chuàng)建密鑰后返回的公鑰,quorum目前不知道(TODO),alias是用戶填寫(xiě)的帳戶別名
  • 2.2這一句沒(méi)有作用(經(jīng)過(guò)官方確認(rèn)了),因?yàn)槲以诖a中沒(méi)有找到處理CREATE_REGISTER_KEY的代碼。可以看這個(gè)issue#28
  • 2.3調(diào)用后臺(tái)創(chuàng)建帳戶,把a(bǔ)ccountData傳過(guò)去,可以拿到返回的resp
  • 2.4調(diào)用成功后,再使用redux的dispatch函數(shù)分發(fā)一個(gè)CREATE_REGISTER_ACCOUNT信息。不過(guò)這個(gè)信息好像也沒(méi)有太大用處。
  • 關(guān)于CREATE_REGISTER_ACCOUNT,我在代碼中找到了兩處相關(guān):

  • src/features/core/reducers.js#L229-L234
  • const accountInit = (state = false, action) => {if (action.type == 'CREATE_REGISTER_ACCOUNT') {return true}return state }
  • src/features/app/reducers.js#L10-L115
  • export const flashMessages = (state = {}, action) => {switch (action.type) {// ...case 'CREATE_REGISTER_ACCOUNT': {return newSuccess(state, 'CREATE_REGISTER_ACCOUNT')}// ...} }

    第一個(gè)看起來(lái)沒(méi)什么用,第二個(gè)應(yīng)該是用來(lái)在操作完成后,顯示相關(guān)的錯(cuò)誤信息。

    那就讓我們把關(guān)注點(diǎn)放在1.2和2.3這兩個(gè)后臺(tái)調(diào)用的地方吧。

  • chainClient().mockHsm.keys.create(keyData)對(duì)應(yīng)的是:
  • src/sdk/api/mockHsmKeys.js#L3-L31

    const mockHsmKeysAPI = (client) => {return {create: (params, cb) => {let body = Object.assign({}, params)const uri = body.xprv ? '/import-private-key' : '/create-key'return shared.tryCallback(client.request(uri, body).then(data => data),cb)},// ...} }

    可以看到在create方法中,如果找不到body.xprv(就是本文對(duì)應(yīng)的情況),則會(huì)調(diào)用后臺(tái)的/create-key接口。經(jīng)過(guò)一長(zhǎng)串的跟蹤,我們終于找到了一個(gè)。

  • chainClient().accounts.create(accountData)對(duì)應(yīng)的是:
  • src/sdk/api/accounts.js#L3-L30

    const accountsAPI = (client) => {return {create: (params, cb) => shared.create(client, '/create-account', params, {cb, skipArray: true}),// ...} }

    很快我們?cè)谶@邊,也找到了創(chuàng)建帳戶時(shí)調(diào)用的接口為/create-account

    前端這邊,我們終于分析完了。下一步,將進(jìn)入比原的節(jié)點(diǎn)(也就是后端)。

    后端:比原的后端是如何接收到數(shù)據(jù)的?

    如果我們對(duì)前一篇文章還有印象的話,會(huì)記得比原在啟動(dòng)之后,會(huì)在Node.initAndstartApiServer方法中啟動(dòng)web api對(duì)應(yīng)的http服務(wù),并且在API.buildHandler()方法中會(huì)配置很多的功能點(diǎn),其中一定會(huì)有我們這里調(diào)用的接口。

    讓我們看看API.buildHandler方法:

    api/api.go#L164-L244

    func (a *API) buildHandler() {walletEnable := falsem := http.NewServeMux()if a.wallet != nil {walletEnable = true// ...m.Handle("/create-account", jsonHandler(a.createAccount))// ...m.Handle("/create-key", jsonHandler(a.pseudohsmCreateKey))// ...

    很快,我們就發(fā)現(xiàn)了:

  • /create-account: 對(duì)應(yīng)a.createAccount
  • /create-key: 對(duì)應(yīng)a.pseudohsmCreateKey
  • 讓我們先看一下a.pseudohsmCreateKey:

    api/hsm.go#L23-L32

    func (a *API) pseudohsmCreateKey(ctx context.Context, in struct {Alias string `json:"alias"`Password string `json:"password"` }) Response {// ... }

    可以看到,pseudohsmCreateKey的第二個(gè)參數(shù),是一個(gè)struct,它有兩個(gè)字段,分別是Alias和Password,這正好和前面從前端傳過(guò)來(lái)的參數(shù)keyData對(duì)應(yīng)。那么這個(gè)參數(shù)的值是怎么由提交的JSON數(shù)據(jù)轉(zhuǎn)換過(guò)來(lái)的呢?上次我們說(shuō)到,主要是由a.pseudohsmCreateKey外面套著的那個(gè)jsonHandler進(jìn)行的,它會(huì)處理與http協(xié)議相關(guān)的操作,以及把JSON數(shù)據(jù)轉(zhuǎn)換成這里需要的Go類型的參數(shù),pseudohsmCreateKey就可以直接用了。

    由于在這個(gè)小問(wèn)題中,我們問(wèn)題的邊界是比原后臺(tái)是如何拿到數(shù)據(jù)的,所以我們到這里就可以停止對(duì)這個(gè)方法的分析了。它具體是怎么創(chuàng)建密鑰的,這在以后的文章中將詳細(xì)討論。

    再看a.createAccount:

    api/accounts.go#L15-L30

    // POST /create-account func (a *API) createAccount(ctx context.Context, ins struct {RootXPubs []chainkd.XPub `json:"root_xpubs"`Quorum int `json:"quorum"`Alias string `json:"alias"` }) Response {// ... }

    與前面一樣,這個(gè)方法的參數(shù)RootXPubs、Quorum和Alias也是由前端提交,并且由jsonHandler自動(dòng)轉(zhuǎn)換好的。

    當(dāng)我們清楚了在本文中,前后端數(shù)據(jù)是如何交互的,就很容易推廣到更多的情景。在前端還在很多的頁(yè)面和表單,在很多地方都需要調(diào)用后端的接口,我相信按照本文的思路,應(yīng)該都可以快速的找到。如果有比較特殊的情況,我們以后會(huì)再專門寫(xiě)文章講解。

    轉(zhuǎn)載于:https://my.oschina.net/u/3886279/blog/1861147

    總結(jié)

    以上是生活随笔為你收集整理的剥开比原看代码09:通过dashboard创建密钥时,前端的数据是如何传到后端的?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美一级欧美三级在线观看 | 久久久久久久久久一区二区 | 人人妻人人澡人人爽精品欧美一区 | 成人99| 少妇高潮伦 | 国产福利视频一区 | 越南a级片| 国产精品入口久久 | 国产啊啊啊啊 | 国产青青草 | 免费荫蒂添的好舒服视频 | 国产爽视频 | 人妖av在线 | 美女91网站 | 亚洲第一毛片 | 亚洲18在线看污www麻豆 | 国产精品黄色av | 国产青青草在线 | 日韩一二三区在线观看 | 一区二区精品在线 | 国产精品美女久久久免费 | 午夜日韩欧美 | 播放灌醉水嫩大学生国内精品 | 午夜动态图 | 日韩成人在线视频观看 | 国产日产欧洲无码视频 | 午夜av中文字幕 | 国产视频污 | 不卡日韩 | 黑丝美女啪啪 | 综合av第一页| 欧美一级影院 | 精品无码成人久久久久久免费 | 欧美四区 | 天天爽天天| 最新一区二区三区 | av一二区| 国产一区二区视频在线免费观看 | 亚洲免费看黄 | 午夜两性| 精品人妻伦一区二区三区久久 | 成人羞羞国产免费游戏 | 青青草中文字幕 | 伊人精品 | 又大又粗又爽18禁免费看 | 久久香蕉综合 | 欧美日韩毛片 | 偷拍自拍一区 | 中国在线观看免费视频 | 动漫美女被吸乳奶动漫视频 | 国产精品乱 | 成人av影院 | 欧美黄色a级 | 咪咪成人网 | 欧美91av | 亚洲一卡二卡在线观看 | 国产色秀视频 | 色老大视频 | 国产激情无码一区二区 | 国产最新自拍 | 久久天堂av | 奇米精品一区二区三区在线观看 | 午夜美女在线 | 毛片99 | 先锋影音资源av | 韩国三级hd两男一女 | 亚洲综合小说网 | 国产911在线观看 | 精品午夜一区二区三区 | 色哟哟免费 | 污的网站 | 日本 奴役 捆绑 受虐狂xxxx | 夜夜久久 | 一级特黄色大片 | 一区二区福利视频 | 亚洲精品99久久久久中文字幕 | 国内自拍亚洲 | 欧美成人hd | 国产片一区二区 | 偷啪自啪| 国产一区二区视频在线播放 | 日韩乱码人妻无码中文字幕久久 | 精品久久久无码中文字幕边打电话 | 黑人巨大精品欧美黑白配亚洲 | 亚洲av男人的天堂在线观看 | 亚洲精品国产精品国自产观看浪潮 | 手机亚洲第一页 | 国产一级片 | 国产主播福利在线 | 69视频一区 | 欧洲中文字幕日韩精品成人 | 欧美日韩成人一区二区 | 亚洲女同女同女同女同女同69 | 美女撒尿无遮挡网站 | 国产精品久久综合视频 | av一区二区在线播放 | 日日骑夜夜操 | 午夜av中文字幕 | 日本美女交配 |