摘要:項目中前端開發(fā)問題經(jīng)驗總結(jié)下的安全限制問題問題描述數(shù)據(jù)看板中的數(shù)據(jù)大部分都是實時數(shù)據(jù)或前一天統(tǒng)計的歷史數(shù)據(jù),因此這邊后端考慮采用來實時和定時推送數(shù)據(jù)來保證數(shù)據(jù)的實時性和有效性。
項目中前端開發(fā)問題經(jīng)驗總結(jié) ie下websocket的安全限制問題
問題描述:
數(shù)據(jù)看板中的數(shù)據(jù)大部分都是實時數(shù)據(jù)或前一天統(tǒng)計的歷史數(shù)據(jù),因此這邊后端考慮采用websocket來實時和定時推送數(shù)據(jù)來保證數(shù)據(jù)的實時性和有效性。而前端開發(fā)這邊為了提高前端開發(fā)的復(fù)用性,采用了在各個組件中開發(fā)成一個個的小部件,然后在門戶通過vue異步動態(tài)加載的方式來實現(xiàn),小部件的組裝拼接。 因此在組件中開發(fā)的小部件都是單vue頁面。因此出現(xiàn)了有幾個小部件就有幾個websocket,目前我這邊就出現(xiàn)了7個websocket。
問題現(xiàn)象:
在ie瀏覽器下,打開時就會發(fā)現(xiàn)報錯。IE控制臺會報SecurityError錯誤。
解決方法:
造成上述現(xiàn)象的原因是ie下websocket連接做了安全限制,如果websocket連接超過6個時,那么就會連接失敗。默認(rèn)最大連接數(shù)為6個。
那么如何避免報錯呢?
當(dāng)然ie下的限制我們是不好修改的,如果真的強(qiáng)制修改,那么可以通過修改注冊表來修改最大連接數(shù)(當(dāng)然這邊是不建議的,不可能讓客戶區(qū)修改瀏覽器注冊表的)。
那么我們需要的就是避免多個websocket的連接。
2個思路:
使用websocket之前先思考,是否真的有必要使用wesocket??
如果是實時推送,定時推送這些場景,那么完全沒有必要使用websocket,前端可通過定時器來實現(xiàn)相同的功能。因此能避免使用就避免使用。
如果是報警等未知的推送,那么我們就是必須要使用websocket的,而且如果正好應(yīng)用在了看板小部件上。那么還是會出現(xiàn)7個websocket的情況。所以這種情況下就需要和后端溝通,一個項目采用一個websocket服務(wù),通過type來區(qū)分。那么看板就只有一個websocket了。可是現(xiàn)在看板的小部件都是獨立,如何去實現(xiàn)一個websocket?那么需要借助一下事件通信。如下:
a.vue created () { this.$root.eventBus = new Vue() this.init() }, methods: { init (i) { let ws = new WebSocket() ws.onmessage = (data) => { this.$root.eventBus.$emit("websocket", data) } } } b.vue created () { this.$root.eventBus.$on("websocket", () => { // 處理推送的數(shù)據(jù) }) }
我們知道我們的小部件都是通過在門戶,通過vue動態(tài)加載組件的方式來形成看板的,那么所以小部件就都會在門戶這個vue實例對象下。所以可以采用this.$root下掛在一個vue實例來實現(xiàn)事件的傳遞
備注:
另外如果你一個頁面中只有4個websocket,而認(rèn)為ie下就不會報錯,請不要這要處理,也請使用type的形式來處理。因為ie下刷新頁面銷毀websocket是時間延遲的。第一次進(jìn)入頁面websocket連接是正常的,而舒心頁面后,可能就會造成2個websocket連接失敗。
問題描述:在使用hui控件的時候,會出現(xiàn)某些bug,然后bug修改后,項目中應(yīng)用的hui版本也對應(yīng)的升級。但是這種情況下,可能會出現(xiàn)hui內(nèi)置多語言增加了一些字段,導(dǎo)致項目中會出現(xiàn)有未翻譯的字段。
解決方法:
在我們各個組件框架下的i18n下面有一個hui.js文件,這個文件內(nèi)部就是hui的多語言,這個多語言版本是在腳手架完成的時候就已經(jīng)創(chuàng)建了,它是不會隨著hui的升級而變化,因此我們就需要從hui那邊去拿到最新的包(node_modules/hui/lib/locale/lang/zh-CN.js),然后再替換更新。
當(dāng)然我們除了手動這樣替換之外,我們也可以直接引用這個文件,那么之后就不需要再替換了。(當(dāng)然翻譯的文件還是需要更具index.json來翻譯最新的)
把hui.js替換成以下代碼那么中文狀態(tài)就可以隨著hui的升級而變化了
hui.js 修改前: let hui = { colorpicker: { confirm: "確定", clear: "清空" }, ....等所以hui的key值 } export default hui 修改后: import hui from "hui/lib/locale/lang/zh-CN.js" export default hui.el // 這邊是因為hui內(nèi)部包了一層el,所以直接拋出hui.el的對象
多語言問題的拓展:
在組件中開發(fā)中怎么使用多語言呢?之前組件開發(fā)我都是把變量拋到外面,通過調(diào)用者傳遞參數(shù)進(jìn)來,那么外面肯定都是已經(jīng)轉(zhuǎn)過多語言的了,那么這種肯定是沒問題的,當(dāng)然這不是特別好的。因此這邊把hui-pro如何使用多語言的方式來說明一下,以后開發(fā)組件中遇到多語言問題都可以這樣操作,向hui那樣把語言放到項目工程中。
首先在工程中需要創(chuàng)建對應(yīng)的語言js文件如zh_CN.js
然后在創(chuàng)建一個調(diào)用的方式:
import defaultLang from "hui-pro/src/locale/lang/zh-CN"; import Vue from "vue"; import deepmerge from "deepmerge"; import Format from "./format"; const format = Format(Vue); let lang = defaultLang; let merged = false; let i18nHandler = function() { const vuei18n = Object.getPrototypeOf(this || Vue).$t; if (typeof vuei18n === "function" && !!Vue.locale) { if (!merged) { merged = true; Vue.locale( Vue.config.lang, deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true }) ); } return vuei18n.apply(this, arguments); } }; export const t = function(path, options) { let value = i18nHandler.apply(this, arguments); if (value !== null && value !== undefined) return value; const array = path.split("."); let current = lang; for (let i = 0, j = array.length; i < j; i++) { const property = array[i]; value = current[property]; if (i === j - 1) return format(value, options); if (!value) return ""; current = value; } return ""; }; export const use = function(l) { lang = l || lang; }; export const i18n = function(fn) { i18nHandler = fn || i18nHandler; }; export default { use, t, i18n };
這個js文件是用于合并工程中的多語言或自己翻譯t函數(shù)就是對外組件使用多語言的方法。
這邊通過做一個mixins
import { t } from "hui-pro/src/locale"; export default { methods: { t(...args) { return t.apply(this, args); } } };
然后直接在組件中使用該mixins即可
{{ t(`h.common.add`) }} import Locale from "hui-pro/src/mixins/locale"; export default { mixins: [Locale] }require的使用問題
問題描述: 目前這邊有那么一種場景,前端有一些列的城市的json文件,而前端需要根據(jù)后端的返回值來調(diào)用相應(yīng)的城市json文件。對于這種情況下:我就使用了require加載動態(tài)文件的方式來加載,因為require是同步加載的,所以比較方便。使用方式如下
let city 從后端獲取 let cityMap = require(`static/city/${city}.json`); // 后續(xù)根據(jù)cityMap再處理
就以上那么一段代碼在打包的時候會將city下的所以json文件都打包的js里面。(require是提前把所有的文件都打包進(jìn)來,才使得可以動態(tài)的加載)。
造成了js比原來臃腫了很多。(臃腫程度是跟city下json文件大小有關(guān))。然后進(jìn)入對應(yīng)的頁面也會相對要慢一些(js比原先大了一些),這樣用戶體驗不好。
因為對于動態(tài)加載的方式盡量避免(如果文件小的話,那影響不大)
解決方法:
動態(tài)獲取的文件(這邊的city.js,多語言,皮膚包等等)盡量都通過ajax來獲取,這樣打包的js文件會少很多。
為了保證仍是同步的,那么就采用es7的async、await來操作吧
async get () { let city = xxx try { let cityMap = await xxx.get("xxxx") // 在根據(jù)cityMap出咯 } catch {} }門戶看板小部件打包的一些問題
問題描述:之前講述了一篇關(guān)于如何打包小部件的,但是那篇并沒有使用復(fù)雜的頁面,引用第三方插件等。就是單純幾個簡單的頁面的測試。這一次實際打包之后發(fā)現(xiàn)仍然有不少問題需要優(yōu)化:
打包的文件會比較大。這是由于每個單vue文件打包,將所有依賴都打包進(jìn)來了,那么就造成文件過于臃腫,相比于單vue實例的效果會差很多,會重復(fù)打包vue,hui,echarts等一些插件。
因此這邊需要剔除依賴進(jìn)行打包,方法如下:
// webpack配置中增加如下配置項,如還有其他第三方插件都可以配置在如下 externals: { echarts: "echarts", hui: "hui", vue: "vue" },
通過以上過濾,可以講一個文件從幾M縮小到100KB以內(nèi)。
小部件中無法獲取到自己組建內(nèi)部的多語言。
a. 這個是由于小部件內(nèi)部是通過this.$t的形式去調(diào)用i18n來翻譯的。可小部件的環(huán)境發(fā)生了變化,通過門戶動態(tài)調(diào)用組件的方式加載,那么小部件所在的環(huán)境就是門戶的vue實例對象,那么i18n也就是門戶的,所以小部件就無法得到翻譯。
b. http的實例對象內(nèi)部也不可以通過i18n以及{message} from "hui"這些。原因是已經(jīng)剔除了這些依賴,那么打包后就會報錯,i18n和hui不存在。
解決方法: 通過一個配置文件里面存放自己組件中的i18n的json文件路徑(/oams/static/i18n/zh-CN/index.json),以及一個keys字段。將看板的部件多語言文件給讓門戶下載,并跟門戶自己的多語言合并(因此多語言key一定要加上自己的上下文或其他來和門戶區(qū)分,不要字段重疊)。這些組件內(nèi)部通過this.$t也都能正常翻譯。
問題描述: 目前前端都使用了統(tǒng)一的前端請求封裝,http都做了一些處理如登錄過期跳登陸頁,可上傳組件是組件內(nèi)部自己ajax請求,因此是不會做這些特殊處理。因此在組件內(nèi)部需要自己做一下
解決方法:
如果當(dāng)前已經(jīng)登錄過期,那么后端單點登錄針對Content-Type為application/json都是后端做了一層處理,返回errorCode為pleaseRefreshByHeader,那么前端根據(jù)這個值來跳登錄頁。可是上傳組件的Content-Type:multipart/form-data,這種類型的單點登錄是直接進(jìn)行攔截而不會經(jīng)過后端,直接返回錯誤頁面。
那么我們就需要針對返回的頁面做特殊處理
uploadSuccess (res, file) { if (res.code === "0") { this.$message.success(this.$t(`oams_common.addSuccess`)) this.addMapDialog = false this.$emit("add-map-success") } else { // 頁面過期處理 if (res.includes && res.includes("html")) { let refreshUrl = "/isecure/cas/login?service=" + location.protocol + "http://" + location.host + location.pathname location.href = refreshUrl } else { // 錯誤碼處理 this.$message.error(this.$t(`oams_errorcode.${res.code}`)) this.$refs.mapUpload.clearFiles() this.$nextTick(() => { this.mapForm.filename = "" }) } } }
除了上面的方法還可以在上傳組件前,先自己發(fā)送一個接口驗證當(dāng)前頁面是否已經(jīng)過期,如果已經(jīng)過期,那么它就會自動跳轉(zhuǎn)首頁了(自己的接口都是經(jīng)過處理的),而且這也不單單處理了單點登錄,網(wǎng)絡(luò)超時也做了相應(yīng)了處理。(上傳組件是沒有做超時處理的,因為不知道文件上傳需要多久,如果設(shè)置了,網(wǎng)絡(luò)差的情況下可能上傳文件或圖片就失敗了)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102570.html
摘要:不過幸運的是所有面試的公司都給了,在這里總結(jié)下經(jīng)驗吧。這里推薦下我當(dāng)時看的一篇的面經(jīng),木易楊老師寫的大廠高級前端面試題匯總。 前言 本人畢業(yè)一年,最近陸續(xù)面試了頭條、瓜子、360、猿輔導(dǎo)、中信銀行、老虎等公司,由于最近比較寒冬而且招1-3年的并不多,再加上自己對公司規(guī)模和位置有一定要求,所以最后合適的也就這幾家了。不過幸運的是所有面試的公司都給了offer,在這里總結(jié)下經(jīng)驗吧。掘金:h...
摘要:參與者項目經(jīng)理產(chǎn)品經(jīng)理開發(fā)經(jīng)理測試經(jīng)理及其它相關(guān)人員。項目上線后問題反饋針對項目客戶反饋問題進(jìn)行分析總結(jié),類似缺陷分析,重點總結(jié)遺漏的原因及后需的規(guī)避措施。六匯總整理各部門總結(jié)并發(fā)布基于測試總結(jié)過程中的數(shù)據(jù)分析,我們提出了對部門的建議。 最近參與了幾次面試,面試者的簡歷中都會提及:需求或者...
摘要:每一個項目過后,我們總是有各種各樣的體會,這些體會就是我們的收獲,也是我們成長的源泉,也許過了一段時間我會忘記,但是,筆記能夠讓他們清晰的保留下來綠網(wǎng)項目寧肯走的慢一點,也要保證方向是正確的注意無論做什么項目,首先,我們需要清晰的明確大的環(huán) 每一個項目過后,我們總是有各種各樣的體會,這些體會就是我們的收獲,也是我們成長的源泉,也許過了一段時間我會忘記,但是,筆記能夠讓他們清晰的保留下來...
摘要:經(jīng)驗少的程序員小猿同學(xué)畢業(yè)工作一年了,在公司感覺自己的能力很好了,能力大于老板給的價值了,所以想要漲工資,但是老板給漲的不夠理想,小猿聽說跳槽可以讓自己的工資翻倍,毅然決然的就辭職了,決定重新找工作。 又到了一周一次的周末心靈雞湯的時間了,希望大家能夠痛痛快快的喝了這碗雞湯,讓這酸爽的感覺使你永生難忘。哈哈……這周又有幾個人,尤其是畢業(yè)生在「非著名程序員」微信公眾號里私聊我關(guān)于找不到工...
閱讀 3114·2023-04-25 15:44
閱讀 1886·2019-08-30 13:11
閱讀 2846·2019-08-30 11:11
閱讀 3064·2019-08-29 17:21
閱讀 1316·2019-08-29 15:38
閱讀 958·2019-08-29 12:49
閱讀 1806·2019-08-28 18:19
閱讀 3232·2019-08-26 14:01