主頁 > 企業開發 > 前端模塊化詳解(完整版)

前端模塊化詳解(完整版)

2021-01-27 07:45:54 企業開發

前言

在JavaScript發展初期就是為了實作簡單的頁面互動邏輯,寥寥數語即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗證等),隨著web2.0時代的到來,Ajax技術得到廣泛應用,jQuery等前端庫層出不窮,前端代碼日益膨脹,此時在JS方面就會考慮使用模塊化規范去管理,
本文內容主要有理解模塊化,為什么要模塊化,模塊化的優缺點以及模塊化規范,并且介紹下開發中最流行的CommonJS, AMD, ES6、CMD規范,本文試圖站在小白的角度,用通俗易懂的筆調介紹這些枯燥無味的概念,希望諸君閱讀后,對模塊化編程有個全新的認識和理解!

一、模塊化的理解

1.什么是模塊?

  • 將一個復雜的程式依據一定的規則(規范)封裝成幾個塊(檔案), 并進行組合在一起
  • 塊的內部資料與實作是私有的, 只是向外部暴露一些介面(方法)與外部其它模塊通信

2.模塊化的進化程序

  • 全域function模式 : 將不同的功能封裝成不同的全域函式
    • 編碼: 將不同的功能封裝成不同的全域函式
    • 問題: 污染全域命名空間, 容易引起命名沖突或資料不安全,而且模塊成員之間看不出直接關系
function m1(){
  //...
}
function m2(){
  //...
}
  • namespace模式 : 簡單物件封裝
    • 作用: 減少了全域變數,解決命名沖突
    • 問題: 資料不安全(外部可以直接修改模塊內部的資料)
let myModule = {
  data: 'www.baidu.com',
  foo() {
    console.log(`foo() ${this.data}`)
  },
  bar() {
    console.log(`bar() ${this.data}`)
  }
}
myModule.data = 'https://www.cnblogs.com/xzsj/archive/2021/01/26/other data' //能直接修改模塊內部的資料
myModule.foo() // foo() other data

這樣的寫法會暴露所有模塊成員,內部狀態可以被外部改寫,

  • IIFE模式:匿名函式自呼叫(閉包)
    • 作用: 資料是私有的, 外部只能通過暴露的方法操作
    • 編碼: 將資料和行為封裝到一個函式內部, 通過給window添加屬性來向外暴露介面
    • 問題: 如果當前這個模塊依賴另一個模塊怎么辦?
// index.html檔案
<script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/module.js"></script>
<script type="text/javascript">
    myModule.foo()
    myModule.bar()
    console.log(myModule.data) //undefined 不能訪問模塊內部資料
    myModule.data = 'https://www.cnblogs.com/xzsj/archive/2021/01/26/xxxx' //不是修改的模塊內部的data
    myModule.foo() //沒有改變
</script>
// module.js檔案
(function(window) {
  let data = 'https://www.cnblogs.com/xzsj/archive/2021/01/26/www.baidu.com'
  //操作資料的函式
  function foo() {
    //用于暴露有函式
    console.log(`foo() ${data}`)
  }
  function bar() {
    //用于暴露有函式
    console.log(`bar() ${data}`)
    otherFun() //內部呼叫
  }
  function otherFun() {
    //內部私有的函式
    console.log('otherFun()')
  }
  //暴露行為
  window.myModule = { foo, bar } //ES6寫法
})(window)

最后得到的結果:

  • IIFE模式增強 : 引入依賴

這就是現代模塊實作的基石

// module.js檔案
(function(window, $) {
  let data = 'https://www.cnblogs.com/xzsj/archive/2021/01/26/www.baidu.com'
  //操作資料的函式
  function foo() {
    //用于暴露有函式
    console.log(`foo() ${data}`)
    $('body').css('background', 'red')
  }
  function bar() {
    //用于暴露有函式
    console.log(`bar() ${data}`)
    otherFun() //內部呼叫
  }
  function otherFun() {
    //內部私有的函式
    console.log('otherFun()')
  }
  //暴露行為
  window.myModule = { foo, bar }
})(window, jQuery)
 // index.html檔案
  <!-- 引入的js必須有一定順序 -->
  <script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/jquery-1.10.1.js"></script>
  <script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/module.js"></script>
  <script type="text/javascript">
    myModule.foo()
  </script>

上例子通過jquery方法將頁面的背景顏色改成紅色,所以必須先引入jQuery庫,就把這個庫當作引數傳入,這樣做除了保證模塊的獨立性,還使得模塊之間的依賴關系變得明顯

3. 模塊化的好處

  • 避免命名沖突(減少命名空間污染)
  • 更好的分離, 按需加載
  • 更高復用性
  • 高可維護性

4. 引入多個<script>后出現出現問題

  • 請求過多

首先我們要依賴多個模塊,那樣就會發送多個請求,導致請求過多

  • 依賴模糊

我們不知道他們的具體依賴關系是什么,也就是說很容易因為不了解他們之間的依賴關系導致加載先后順序出錯,

  • 難以維護

以上兩種原因就導致了很難維護,很可能出現牽一發而動全身的情況導致專案出現嚴重的問題,
模塊化固然有多個好處,然而一個頁面需要引入多個js檔案,就會出現以上這些問題,而這些問題可以通過模塊化規范來解決,下面介紹開發中最流行的commonjs, AMD, ES6, CMD規范,

二、模塊化規范

1.CommonJS

(1)概述

Node 應用由模塊組成,采用 CommonJS 模塊規范,每個檔案就是一個模塊,有自己的作用域,在一個檔案里面定義的變數、函式、類,都是私有的,對其他檔案不可見,在服務器端,模塊的加載是運行時同步加載的;在瀏覽器端,模塊需要提前編譯打包處理,

(2)特點

  • 所有代碼都運行在模塊作用域,不會污染全域作用域,
  • 模塊可以多次加載,但是只會在第一次加載時運行一次,然后運行結果就被快取了,以后再加載,就直接讀取快取結果,要想讓模塊再次運行,必須清除快取,
  • 模塊加載的順序,按照其在代碼中出現的順序,

(3)基本語法

  • 暴露模塊:module.exports = valueexports.xxx = value
  • 引入模塊:require(xxx),如果是第三方模塊,xxx為模塊名;如果是自定義模塊,xxx為模塊檔案路徑

此處我們有個疑問:CommonJS暴露的模塊到底是什么? CommonJS規范規定,每個模塊內部,module變數代表當前模塊,這個變數是一個物件,它的exports屬性(即module.exports)是對外的介面,加載某個模塊,其實是加載該模塊的module.exports屬性

// example.js
var x = 5;
var addX = function (value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

上面代碼通過module.exports輸出變數x和函式addX,

var example = require('./example.js');//如果引數字串以“./”開頭,則表示加載的是一個位于相對路徑
console.log(example.x); // 5
console.log(example.addX(1)); // 6

require命令用于加載模塊檔案,require命令的基本功能是,讀入并執行一個JavaScript檔案,然后回傳該模塊的exports物件,如果沒有發現指定模塊,會報錯

(4)模塊的加載機制

CommonJS模塊的加載機制是,輸入的是被輸出的值的拷貝,也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值,這點與ES6模塊化有重大差異(下文會介紹),請看下面這個例子:

// lib.js
var counter = 3;
function incCounter() {
  counter++;
}
module.exports = {
  counter: counter,
  incCounter: incCounter,
};

上面代碼輸出內部變數counter和改寫這個變數的內部方法incCounter,

// main.js
var counter = require('./lib').counter;
var incCounter = require('./lib').incCounter;

console.log(counter);  // 3
incCounter();
console.log(counter); // 3

上面代碼說明,counter輸出以后,lib.js模塊內部的變化就影響不到counter了,這是因為counter是一個原始型別的值,會被快取,除非寫成一個函式,才能得到內部變動后的值

(5)服務器端實作

①下載安裝node.js

②創建專案結構

注意:用npm init 自動生成package.json時,package name(包名)不能有中文和大寫

|-modules
  |-module1.js
  |-module2.js
  |-module3.js
|-app.js
|-package.json
  {
    "name": "commonJS-node",
    "version": "1.0.0"
  }

③下載第三方模塊

npm install uniq --save // 用于陣列去重

④定義模塊代碼

//module1.js
module.exports = {
  msg: 'module1',
  foo() {
    console.log(this.msg)
  }
}
//module2.js
module.exports = function() {
  console.log('module2')
}
//module3.js
exports.foo = function() {
  console.log('foo() module3')
}
exports.arr = [1, 2, 3, 3, 2]
// app.js檔案
// 引入第三方庫,應該放置在最前面
let uniq = require('uniq')
let module1 = require('./modules/module1')
let module2 = require('./modules/module2')
let module3 = require('./modules/module3')

module1.foo() //module1
module2() //module2
module3.foo() //foo() module3
console.log(uniq(module3.arr)) //[ 1, 2, 3 ]

⑤通過node運行app.js

命令列輸入node app.js,運行JS檔案

(6)瀏覽器端實作(借助Browserify)

①創建專案結構

|-js
  |-dist //打包生成檔案的目錄
  |-src //原始碼所在的目錄
    |-module1.js
    |-module2.js
    |-module3.js
    |-app.js //應用主源檔案
|-index.html //運行于瀏覽器上
|-package.json
  {
    "name": "browserify-test",
    "version": "1.0.0"
  }

②下載browserify

  • 全域: npm install browserify -g
  • 區域: npm install browserify --save-dev

③定義模塊代碼(同服務器端)

注意:index.html檔案要運行在瀏覽器上,需要借助browserify將app.js檔案打包編譯,如果直接在index.html引入app.js就會報錯!

④打包處理js

根目錄下運行browserify js/src/app.js -o js/dist/bundle.js

⑤頁面使用引入

在index.html檔案中引入<script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/dist/bundle.js"></script>

2.AMD

CommonJS規范加載模塊是同步的,也就是說,只有加載完成,才能執行后面的操作,AMD規范則是非同步加載模塊,允許指定回呼函式,由于Node.js主要用于服務器編程,模塊檔案一般都已經存在于本地硬碟,所以加載起來比較快,不用考慮非同步加載的方式,所以CommonJS規范比較適用,但是,如果是瀏覽器環境,要從服務器端加載模塊,這時就必須采用非同步模式,因此瀏覽器端一般采用AMD規范,此外AMD規范比CommonJS規范在瀏覽器端實作要來著早,

(1)AMD規范基本語法

定義暴露模塊:

//定義沒有依賴的模塊
define(function(){
   return 模塊
})
//定義有依賴的模塊
define(['module1', 'module2'], function(m1, m2){
   return 模塊
})

引入使用模塊:

require(['module1', 'module2'], function(m1, m2){
   使用m1/m2
})

(2)未使用AMD規范與使用require.js

通過比較兩者的實作方法,來說明使用AMD規范的好處,

  • 未使用AMD規范
// dataService.js檔案
(function (window) {
  let msg = 'www.baidu.com'
  function getMsg() {
    return msg.toUpperCase()
  }
  window.dataService = {getMsg}
})(window)
// alerter.js檔案
(function (window, dataService) {
  let name = 'Tom'
  function showMsg() {
    alert(dataService.getMsg() + ', ' + name)
  }
  window.alerter = {showMsg}
})(window, dataService)
// main.js檔案
(function (alerter) {
  alerter.showMsg()
})(alerter)
// index.html檔案
<div><h1>Modular Demo 1: 未使用AMD(require.js)</h1></div>
<script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/modules/dataService.js"></script>
<script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/modules/alerter.js"></script>
<script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/main.js"></script>

最后得到如下結果:

這種方式缺點很明顯:首先會發送多個請求,其次引入的js檔案順序不能搞錯,否則會報錯!

  • 使用require.js

RequireJS是一個工具庫,主要用于客戶端的模塊管理,它的模塊管理遵守AMD規范,RequireJS的基本思想是,通過define方法,將代碼定義為模塊;通過require方法,實作代碼的模塊加載
接下來介紹AMD規范在瀏覽器實作的步驟:

①下載require.js, 并引入

  • 官網: http://www.requirejs.cn/
  • github : https://github.com/requirejs/requirejs

然后將require.js匯入專案: js/libs/require.js

②創建專案結構

|-js
  |-libs
    |-require.js
  |-modules
    |-alerter.js
    |-dataService.js
  |-main.js
|-index.html

③定義require.js的模塊代碼

// dataService.js檔案
// 定義沒有依賴的模塊
define(function() {
  let msg = 'www.baidu.com'
  function getMsg() {
    return msg.toUpperCase()
  }
  return { getMsg } // 暴露模塊
})
//alerter.js檔案
// 定義有依賴的模塊
define(['dataService'], function(dataService) {
  let name = 'Tom'
  function showMsg() {
    alert(dataService.getMsg() + ', ' + name)
  }
  // 暴露模塊
  return { showMsg }
})
// main.js檔案
(function() {
  require.config({
    baseUrl: 'js/', //基本路徑 出發點在根目錄下
    paths: {
      //映射: 模塊標識名: 路徑
      alerter: './modules/alerter', //此處不能寫成alerter.js,會報錯
      dataService: './modules/dataService'
    }
  })
  require(['alerter'], function(alerter) {
    alerter.showMsg()
  })
})()
// index.html檔案
<!DOCTYPE html>
<html>
  <head>
    <title>Modular Demo</title>
  </head>
  <body>
    <!-- 引入require.js并指定js主檔案的入口 -->
    <script data-main="js/main" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/libs/require.js"></script>
  </body>
</html>

④頁面引入require.js模塊:

在index.html引入 <script data-main="js/main" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/libs/require.js"></script>

此外在專案中如何引入第三方庫?只需在上面代碼的基礎稍作修改:

// alerter.js檔案
define(['dataService', 'jquery'], function(dataService, $) {
  let name = 'Tom'
  function showMsg() {
    alert(dataService.getMsg() + ', ' + name)
  }
  $('body').css('background', 'green')
  // 暴露模塊
  return { showMsg }
})
// main.js檔案
(function() {
  require.config({
    baseUrl: 'js/', //基本路徑 出發點在根目錄下
    paths: {
      //自定義模塊
      alerter: './modules/alerter', //此處不能寫成alerter.js,會報錯
      dataService: './modules/dataService',
      // 第三方庫模塊
      jquery: './libs/jquery-1.10.1' //注意:寫成jQuery會報錯
    }
  })
  require(['alerter'], function(alerter) {
    alerter.showMsg()
  })
})()

上例是在alerter.js檔案中引入jQuery第三方庫,main.js檔案也要有相應的路徑配置,
小結:通過兩者的比較,可以得出AMD模塊定義的方法非常清晰,不會污染全域環境,能夠清楚地顯示依賴關系,AMD模式可以用于瀏覽器環境,并且允許非同步加載模塊,也可以根據需要動態加載模塊,

3.CMD

CMD規范專門用于瀏覽器端,模塊的加載是異步的,模塊使用時才會加載執行,CMD規范整合了CommonJS和AMD規范的特點,在 Sea.js 中,所有 JavaScript 模塊都遵循 CMD模塊定義規范,

(1)CMD規范基本語法

定義暴露模塊:

//定義沒有依賴的模塊
define(function(require, exports, module){
  exports.xxx = value
  module.exports = value
})
//定義有依賴的模塊
define(function(require, exports, module){
  //引入依賴模塊(同步)
  var module2 = require('./module2')
  //引入依賴模塊(異步)
    require.async('./module3', function (m3) {
    })
  //暴露模塊
  exports.xxx = value
})

引入使用模塊:

define(function (require) {
  var m1 = require('./module1')
  var m4 = require('./module4')
  m1.show()
  m4.show()
})

(2)sea.js簡單使用教程

①下載sea.js, 并引入

  • 官網: http://seajs.org/
  • github : https://github.com/seajs/seajs

然后將sea.js匯入專案: js/libs/sea.js

②創建專案結構

|-js
  |-libs
    |-sea.js
  |-modules
    |-module1.js
    |-module2.js
    |-module3.js
    |-module4.js
    |-main.js
|-index.html

③定義sea.js的模塊代碼

// module1.js檔案
define(function (require, exports, module) {
  //內部變數資料
  var data = 'https://www.cnblogs.com/xzsj/archive/2021/01/26/atguigu.com'
  //內部函式
  function show() {
    console.log('module1 show() ' + data)
  }
  //向外暴露
  exports.show = show
})
// module2.js檔案
define(function (require, exports, module) {
  module.exports = {
    msg: 'I Will Back'
  }
})
// module3.js檔案
define(function(require, exports, module) {
  const API_KEY = 'abc123'
  exports.API_KEY = API_KEY
})
// module4.js檔案
define(function (require, exports, module) {
  //引入依賴模塊(同步)
  var module2 = require('./module2')
  function show() {
    console.log('module4 show() ' + module2.msg)
  }
  exports.show = show
  //引入依賴模塊(異步)
  require.async('./module3', function (m3) {
    console.log('異步引入依賴模塊3  ' + m3.API_KEY)
  })
})
// main.js檔案
define(function (require) {
  var m1 = require('./module1')
  var m4 = require('./module4')
  m1.show()
  m4.show()
})

④在index.html中引入

<script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/libs/sea.js"></script>
<script type="text/javascript">
  seajs.use('./js/modules/main')
</script>

最后得到結果如下:

4.ES6模塊化

ES6 模塊的設計思想是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變數,CommonJS 和 AMD 模塊,都只能在運行時確定這些東西,比如,CommonJS 模塊就是物件,輸入時必須查找物件屬性,

(1)ES6模塊化語法

export命令用于規定模塊的對外介面,import命令用于輸入其他模塊提供的功能,

/** 定義模塊 math.js **/
var basicNum = 0;
var add = function (a, b) {
    return a + b;
};
export { basicNum, add };
/** 參考模塊 **/
import { basicNum, add } from './math';
function test(ele) {
    ele.textContent = add(99 + basicNum);
}

如上例所示,使用import命令的時候,用戶需要知道所要加載的變數名或函式名,否則無法加載,為了給用戶提供方便,讓他們不用閱讀檔案就能加載模塊,就要用到export default命令,為模塊指定默認輸出,

// export-default.js
export default function () {
  console.log('foo');
}
// import-default.js
import customName from './export-default';
customName(); // 'foo'

模塊默認輸出, 其他模塊加載該模塊時,import命令可以為該匿名函式指定任意名字,

(2)ES6 模塊與 CommonJS 模塊的差異

它們有兩個重大差異:

① CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的參考

② CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出介面

第二個差異是因為 CommonJS 加載的是一個物件(即module.exports屬性),該物件只有在腳本運行完才會生成,而 ES6 模塊不是物件,它的對外介面只是一種靜態定義,在代碼靜態決議階段就會生成,

下面重點解釋第一個差異,我們還是舉上面那個CommonJS模塊的加載機制例子:

// lib.js
export let counter = 3;
export function incCounter() {
  counter++;
}
// main.js
import { counter, incCounter } from './lib';
console.log(counter); // 3
incCounter();
console.log(counter); // 4

ES6 模塊的運行機制與 CommonJS 不一樣,ES6 模塊是動態參考,并且不會快取值,模塊里面的變數系結其所在的模塊

(3) ES6-Babel-Browserify使用教程

簡單來說就一句話:使用Babel將ES6編譯為ES5代碼,使用Browserify編譯打包js

①定義package.json檔案

 {
   "name" : "es6-babel-browserify",
   "version" : "1.0.0"
 }

②安裝babel-cli, babel-preset-es2015和browserify

  • npm install babel-cli browserify -g
  • npm install babel-preset-es2015 --save-dev
  • preset 預設(將es6轉換成es5的所有插件打包)

③定義.babelrc檔案

  {
    "presets": ["es2015"]
  }

④定義模塊代碼

//module1.js檔案
// 分別暴露
export function foo() {
  console.log('foo() module1')
}
export function bar() {
  console.log('bar() module1')
}
//module2.js檔案
// 統一暴露
function fun1() {
  console.log('fun1() module2')
}
function fun2() {
  console.log('fun2() module2')
}
export { fun1, fun2 }
//module3.js檔案
// 默認暴露 可以暴露任意資料類項,暴露什么資料,接收到就是什么資料
export default () => {
  console.log('默認暴露')
}
// app.js檔案
import { foo, bar } from './module1'
import { fun1, fun2 } from './module2'
import module3 from './module3'
foo()
bar()
fun1()
fun2()
module3()

⑤ 編譯并在index.html中引入

  • 使用Babel將ES6編譯為ES5代碼(但包含CommonJS語法) : babel js/src -d js/lib
  • 使用Browserify編譯js : browserify js/lib/app.js -o js/lib/bundle.js

然后在index.html檔案中引入

 <script type="text/javascript" src="https://www.cnblogs.com/xzsj/archive/2021/01/26/js/lib/bundle.js"></script>

最后得到如下結果:

此外第三方庫(以jQuery為例)如何引入呢
首先安裝依賴npm install jquery@1
然后在app.js檔案中引入

//app.js檔案
import { foo, bar } from './module1'
import { fun1, fun2 } from './module2'
import module3 from './module3'
import $ from 'jquery'

foo()
bar()
fun1()
fun2()
module3()
$('body').css('background', 'green')

三、總結

  • CommonJS規范主要用于服務端編程,加載模塊是同步的,這并不適合在瀏覽器環境,因為同步意味著阻塞加載,瀏覽器資源是異步加載的,因此有了AMD CMD解決方案,
  • AMD規范在瀏覽器環境中異步加載模塊,而且可以并行加載多個模塊,不過,AMD規范開發成本高,代碼的閱讀和書寫比較困難,模塊定義方式的語意不順暢,
  • CMD規范與AMD規范很相似,都用于瀏覽器編程,依賴就近,延遲執行,可以很容易在Node.js中運行,不過,依賴SPM 打包,模塊的加載邏輯偏重
  • ES6 在語言標準的層面上,實作了模塊功能,而且實作得相當簡單,完全可以取代 CommonJS 和 AMD 規范,成為瀏覽器和服務器通用的模塊解決方案

作者:浪里行舟
鏈接:前端模塊化詳解(完整版)
來源:github
著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請注明出處,

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

標籤:其他

上一篇:子元素margin-top導致父元素移動的問題

下一篇:ant design vue 地區選擇(級聯)js資料

標籤雲
其他(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