原生node知識總結

一、nodejs安裝

1、普通方式安裝

訪問官網 ,下載,安裝。

運行 node -v 和 npm -v 測試

2、使用nvm安裝

nvm:nodejs 版本管理工具,可以切換多個nodejs版本

mac os :使用 brew install nvm

windows: github 中搜索 nvm-windows

nvm使用:

配置淘寶鏡像:

nvm root  找到 nvm 安裝目錄

找到 settings.txt 文件

添加:

node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/
nvm list 查看當前所有的已安裝的node版本
nvm install v10.13.0 64 安裝置頂版本的nodejs
nvm use 10.13.0 64 切換到指定版本

二、nodejs 和 javascript區別

ECMAScript是語法規範

nodejs = ES + nodejs API

1、ECMAScript

定義了語法,寫JavaScript 和 nodejs都必須遵守

變量定義 ,循環,判斷,函數

原型和原型鏈,作用域和閉包、異步

文檔:http://es6.ruanyifeng.com/

2、javascript

  • 使用ECMAScript語法規範,外加Web API ,缺一不可

  • DOM操作,BOM操作,事件綁定,AJAX等

  • 兩者結合,即可完成瀏覽器端的任何操作

3、nodejs

文檔:http://nodejs.cn/api/

  • 使用ECMAScript語法規範,外加nodejs API ,缺一不可

  • 處理http、處理文件等

  • 兩者結合,即可完成server端的任何操作

三、npm

1、npm引入依賴的版本

"5.0.3",
"~5.0.3",
"^5.0.3"

“5.0.3”表示安裝指定的5.0.3版本,“~5.0.3”表示安裝5.0.X中最新的版本,“^5.0.3”表示安裝5.X.X中最新的版本

四、yarn

npm i yarn -g 全局安裝yarn
npm install -g yrm   yarn鏡像源控制
yrm ls
yrm use taobao
yrm test taobao 
yrm current
yarn config get registry
yarn config set registry https://registry.npm.taobao.org -g
yarn config set electron_mirror https://npm.taobao.org/mirrors/electron/ -g
yarn cache clean
yarn
  • 並行安裝:無論 npm 還是 Yarn 在執行包的安裝時,都會執行一系列任務。npm 是按照隊列執行每個 package,也就是說必須要等到當前 package 安裝完成之後,才能繼續後面的安裝。而 Yarn 是同步執行所有任務,提高了性能。

  • 離線模式:如果之前已經安裝過一個軟件包,用Yarn再次安裝時之間從緩存中獲取,就不用像npm那樣再從網絡下載了。

  • 安裝版本統一:爲了防止拉取到不同的版本,Yarn 有一個鎖定文件 (lock file) 記錄了被確切安裝上的模塊的版本號。每次只要新增了一個模塊,Yarn 就會創建(或更新)yarn.lock 這個文件。這麼做就保證了,每一次拉取同一個項目依賴時,使用的都是一樣的模塊版本。npm 其實也有辦法實現處處使用相同版本的 packages,但需要開發者執行 npm shrinkwrap 命令。這個命令將會生成一個鎖定文件,在執行 npm install 的時候,該鎖定文件會先被讀取,和 Yarn 讀取 yarn.lock 文件一個道理。npm 和 Yarn 兩者的不同之處在於,Yarn 默認會生成這樣的鎖定文件,而 npm 要通過 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有當這個文件存在的時候,packages 版本信息纔會被記錄和更新。
  • 更簡潔的輸出:npm 的輸出信息比較冗長。在執行 npm install 的時候,命令行裏會不斷地打印出所有被安裝上的依賴。相比之下,Yarn 簡潔太多:默認情況下,結合了 emoji直觀且直接地打印出必要的信息,也提供了一些命令供開發者查詢額外的安裝信息。
  • **多註冊來源處理:**所有的依賴包,不管他被不同的庫間接關聯引用多少次,安裝這個包時,只會從一個註冊來源去裝,要麼是 npm 要麼是 bower, 防止出現混亂不一致。
  • 更好的語義化: yarn改變了一些npm命令的名稱,比如 yarn add/remove,感覺上比 npm 原本的 install/uninstall 要更清晰。

Yarn和npm命令對比:

npm yarn
npm install yarn
npm install react --save yarn add react
npm uninstall react --save yarn remove react
npm install react --save-dev yarn add react --dev
npm update --save yarn upgrade

五、commonjs

nodejs裏默認包含commonjs

1、單個導入導出:

a.js

function add(a, b) {
    return a + b
}

module.exports = add

b.js

const add = require('./a')

const sum = add(10, 20)

console.log(sum)

運行:

node b

2、多個導入導出:

a.js

function add(a, b) {
    return a + b
}

function mul(a, b) {
    return a * b
}

module.exports = {add, mul}

b.js

//es6 解構
const {add, mul} = require('./a')

const a = add(10, 20)
const b = mul(100, 200)

console.log(a)
console.log(b);

運行:

node b

但是:如果導出多個的時候是這樣導出的:

module.exports = add
module.exports = mul

第二個會覆蓋第一個導出

3、另外一種導出

function add(a, b) {
    return a + b
}

function mul(a, b) {
    return a * b
}


exports.add=add
exports.mul=mul

console.log(module.exports)

打印

{ add: [Function: add], mul: [Function: mul] }

說明 exports 和 module.exports是一塊內存空間,但是

exports = {'add': add, 'mul': mul}

或者

exports = { add,  mul}

都不可以

4、引入的測試

a.js

function add(a, b) {
    return a + b
}

function mul(a, b) {
    return a * b
}


exports.add = add
exports.mul = mul

b.js 直接引入對象

const a = require('./a')

console.log(a.add(5, 6))
console.log(a.mul(5, 6))

這樣是可以的

5、es6語法ecport和default

export命令規定的是對外的接口,必須與模塊內部的變量建立一一對應關係。

// 寫法一
export var m = 1;

// 寫法二
var m = 1;
export {m};

// 寫法三
var n = 1;
export {n as m};

export default 命令

使用export default命令,爲模塊指定默認輸出。

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

6、引入npm包:

npm i lodash --save --registry=https://registry.npm.taobao.org
const _ = require('lodash')
let arr = _.concat([1, 2], 3)
console.log(arr)
const {concat} = require('lodash')
let arr = concat([1, 2], 3)
console.log(arr)

六、知識節點

1、開發流程

定目標>定需求>定ui設計>定技術方案>開發>聯條>測試>上線>評估

2、pv和uv

pv訪問量(Page View),即頁面訪問量,每打開一次頁面PV計數+1,刷新頁面也是。

UV訪問數(Unique Visitor)指獨立訪客訪問數,一臺電腦終端爲一個訪客。

PV(訪問量):PV反映的是瀏覽某網站的頁面數,所以每刷新一次也算一次。就是說PV與來訪者的數量成正比,但PV並不是頁面的來訪者數量,而是網站被訪問的頁面數量。

UV(獨立訪客):可以理解成訪問某網站的電腦的數量。網站判斷來訪電腦的身份是通過來訪電腦的cookies實現的。如果更換了IP後但不清除cookies,再訪問相同網站,該網站的統計中UV數是不變的。

3、訪問url的過程

  • dns解析,找到ip地址
  • 三次握手,建立tcp連接
  • 發送http請求,數據傳輸
  • server接收到http請求,處理,並返回
  • 客戶端收到返回數據,處理數據(渲染頁面,執行js)
  • TCP四次揮手,斷開連接

三次握手即可建立TCP連接

1、第一次握手:客戶端發送syn包(seq=x)到服務器,並進入SYN_SEND狀態,等待服務器確認;

2、第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(seq=y),即SYN+ACK包,此時服務器進入SYN_RECV狀態;

3、第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。

握手過程中傳送的包裏不包含數據,三次握手完畢後,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。

爲什麼需要三次握手呢?

相互確認!
爲了保證服務端能收接受到客戶端的信息 並能做出正確的應答而進行前兩次(第一次和第二次)握手,爲了保證客戶端能夠接收到服務端的信息 並能做出正確的應答而進行後兩次(第二次和第三次)握手。

買手機的時候試通話功能的時候:

1老機(客戶端)打給新機(服務器) : 喂 , 聽到了嗎 ?

2新機回覆老機 : 聽到了 , 你聽到了嗎 ?

3老機 : 聽到了聽到了 …

四次揮手即可斷開TCP連接

1、第一次揮手:主動關閉方發送一個FIN,用來關閉主動方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方:我已經不會再給你發數據了(當然,在fin包之前發送出去的數據,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些數據),但此時主動關閉方還可以接受數據。

2、第二次揮手:被動關閉方收到FIN包後,發送一個ACK給對方,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號)。

3、第三次揮手:被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,我的數據也發送完了,不會再給你發數據了。

4、第四次揮手:主動關閉方收到FIN後,發送一個ACK給被動關閉方,確認序號爲收到序號+1,至此,完成四次揮手。

白話文:

1、第一次揮手,瀏覽器對服務器說:“煞筆,我不再給你發數據啦,但可以接受數據。”

2、第二次揮手,服務器對瀏覽器說:“騷貨,我知道啦!”

3、第三次揮手,服務器對瀏覽器說:“騷貨,我也不再給你發數據啦!”

4、第四次揮手,瀏覽器對服務器說:“煞筆,我知道啦!”

七、node-http搭建後臺服務

const http = require('http')
const querystring = require('querystring')

module.exports = function () {
    const server = http.createServer((req, res) => {
        const method = req.method
        const url = req.url
        const path = url.split("?")[0]
        const query = querystring.parse(url.split("?")[1])

        //設置返回格式爲json
        res.setHeader('Content-Type', 'application/json')
        //返回的數據
        const resData = {method, url, path, query}
        if (method === "GET") {
            res.end(JSON.stringify(resData))
        }

        if (method === "POST") {
            let postData = ''
            req.on('data', chunk => postData += chunk.toString())
            req.on('end', () => {
                resData.postData = postData
                //返回
                res.end(JSON.stringify(resData))
            })
        }

    })

    server.listen(8000)
    console.log('OK')
}

八、node搭建博客後臺服務

1、cross-env

  • 講解

    它是運行跨平臺設置和使用環境變量(Node中的環境變量)的腳本。

    我們在自定義配置環境變量的時候,由於在不同的環境下,配置方式也是不同的。

    • 例如在window和linux下配置環境變量。
    #node中常用的到的環境變量是NODE_ENV,首先查看是否存在 
    set NODE_ENV 
    
    #如果不存在則添加環境變量 
    set NODE_ENV=production 
    
    #環境變量追加值 set 變量名=%變量名%;變量內容 
    set path=%path%;C:\web;C:\Tools 
    
    #某些時候需要刪除環境變量 
    set NODE_ENV=
    
    • 在linux下配置
    #node中常用的到的環境變量是NODE_ENV,首先查看是否存在
    echo $NODE_ENV
    
    #如果不存在則添加環境變量
    export NODE_ENV=production
    
    #環境變量追加值
    export path=$path:/home/download:/usr/local/
    
    #某些時候需要刪除環境變量
    unset NODE_ENV
    
    #某些時候需要顯示所有的環境變量
    env
    
    • cross-env的作用是什麼?
      當我們使用 NODE_ENV = production 來設置環境變量的時候,大多數windows命令會提示將會阻塞或者異常,或者,windows不支持NODE_ENV=development的這樣的設置方式,會報錯。因此 cross-env 出現了。我們就可以使用 cross-env命令,這樣我們就不必擔心平臺設置或使用環境變量了。也就是說 cross-env 能夠提供一個設置環境變量的scripts,這樣我們就能夠以unix方式設置環境變量,然而在windows上也能夠兼容的。
  • 安裝

    npm install --save-dev cross-env
    
  • package.json中使用

    "scripts": {
        "dev": "cross-env NODE_ENV=dev node ./bin/www",
        "prod": "cross-env NODE_ENV=prod node ./bin/www"
    }
    
  • 獲取環境變量

    cosnt env = process.env.NODE_ENV
    

2、nodemon

nodemon用來監視node.js應用程序中的任何更改並自動重啓服務,非常適合用在開發環境中。

nodemon將監視啓動目錄中的文件,如果有任何文件更改,nodemon將自動重新啓動node應用程序。

nodemon不需要對代碼或開發方式進行任何更改。nodemon只是簡單的包裝你的node應用程序,並監控任何已經改變的文件。nodemon只是node的替換包,只是在運行腳本時將其替換命令行上的node。

安裝在全局。

cnpm install -g  nodemon

九、nodejs操作 mysql

1、安裝mysql插件

yarn add mysql

2、demo

const mysql = require('mysql')

//創建連接對象
const con = mysql.createConnection({
    host: '192.168.100.230',
    user: 'root',
    password: '123456',
    port: '3306',
    database: 'blog'
})

//開始執行
con.connect()

//執行sql語句
const sql = 'select * from user'
con.query(sql, (err, result) => {
    if (err) {
        console.error(err)
        return
    } else {
        console.log(result)
    }
})

const sql2 = "update user set name = 'c' where name = 'b'  "
con.query(sql2, (err, result) => {
    if (err) {
        console.error(err)
        return
    } else {
        console.log(result)
    }
})

//關閉連接
con.end()

3、封裝

配置:

'use strict';
const env = process.env.NODE_ENV; //環境參數
//配置
let MYSQL_CONF

if (env === 'dev') {
    MYSQL_CONF = {
        host: '192.168.100.230',
        user: 'root',
        password: '123456',
        port: '3306',
        database: 'blog'
    }
}

if (env === 'production') {
    MYSQL_CONF = {
        host: 'online' +
            '',
        user: 'root',
        password: '123456',
        port: '3306',
        database: 'blog'
    }
}

module.exports = {
    MYSQL_CONF
}

工具

const mysql = require('mysql')
const {MYSQL_CONF} = require('../conf/db')

//創建連接對象
const con = mysql.createConnection(MYSQL_CONF);

//開始連接
con.connect();

//統一執行sql的函數
function exec(sql) {
    return new Promise((resolve, reject) => {
        con.query(sql, (err, result) => {
            if (err) {
                console.error(err);
                reject(err)
            } else {
                console.log(result);
                resolve(result)
            }
        });
    })
}

module.exports = {
    exec,
    escape: mysql.escape// 預防sql注入
}

十、cookie

1、存儲在瀏覽器中的一段字符串(最大5kb)

2、跨域不共享

3、格式如 k1=v1;k2=v2;因此可以存儲格式化數據

4、每次發送http請求,會將請求與的cookie一起發送給server

5、server可以修改cookie並返回給瀏覽器

6、瀏覽器中也可以通過js修改cookie(有限制)

//js查看cookie
document.cookie
//js累加cookie
document.cookie='k1=v1;'

1、server端nodejs操作cookie

//解析cookie
req.cookie = {}
let cookieStr = req.headers.cookie || "";
cookieStr.split(';').forEach(item => {
    if (!item) {
        return
    }
    let arr = item.split('=');
    let key = arr[0].trim();
    let value = arr[1].trim();
    req.cookie[key] = value;
})

//設置cookie
const getCookieExpires = () => {
    console.log(new Date(Date.now() + 24 * 60 * 60 * 1000).toGMTString())
    return new Date(Date.now() + 24 * 60 * 60 * 1000).toGMTString()
}

res.setHeader('Set-Cookie', `username=${result.username};path=/; httpOnly;expires=${getCookieExpires()}`)

httpOnly:只能通過http修改cookie,用 js修改cookie(document.cookie='username=cc') 只會添加一條新cookie而不是修改原來的cookie,然後帶到後端之後只會接收到原來的cookie;但是可以在瀏覽器的application中直接手動修改原來的cookie


十一、nodejs操作redis

1、安裝

yarn add redis

2、demo

const redis = require('redis')

//創建客戶端
let redisClient = redis.createClient(6379, '192.168.100.142');
redisClient.on('error', err => {
    console.log(err)
})

//測試
redisClient.set('my', 'ha', redis.print)
redisClient.get('my', (err, val) => {
    if (err) {
        console.log(err)
        return
    }
    console.log(val);

    //退出
    redisClient.quit();
})

3、封裝

配置:

'use strict';
const env = process.env.NODE_ENV; //環境參數
//配置
let MYSQL_CONF;
let REDIS_CONF;

if (env === 'dev') {
    MYSQL_CONF = {
        host: '192.168.100.230',
        user: 'root',
        password: '123456',
        port: '3306',
        database: 'blog'
    }

    REDIS_CONF = {
        port: 6379,
        host: '192.168.100.230'
    }
}

if (env === 'production') {
    MYSQL_CONF = {
        host: 'online' +
            '',
        user: 'root',
        password: '123456',
        port: '3306',
        database: 'blog'
    }
    REDIS_CONF = {
        port: 6379,
        host: '192.168.100.230'
    }
}

module.exports = {
    MYSQL_CONF
}

工具redis.js

const redis = require('redis')
const {REDIS_CONF} = require('../conf/db')

//創建客戶端
let redisClient = redis.createClient(REDIS_CONF.port, REDIS_CONF.host);
redisClient.on('error', err => {
    console.log(err)
})

function set(key, value) {
    if (typeof value === 'object') {
        value = JSON.stringify(value)
    }
    redisClient.set(key, value, redis.print)
}

function get(key) {
    return new Promise((resolve, reject) => {
        redisClient.get(key, (err, val) => {
            if (err) {
                reject(err)
                return
            }
            console.log(val);
            if (val == null) {
                resolve(null)
                return;
            }
            try {
                resolve(JSON.parse(val))
            } catch (e) {
                resolve(val)
            }
        })
    })
}

module.exports = {get, set}

十二、nodejs操作文件

1、path.join和path.resolve的區別

path.join() 方法使用平臺特定的分隔符把全部給定的 path 片段連接到一起,並規範化生成的路徑。
長度爲零的 path 片段會被忽略。 如果連接後的路徑字符串是一個長度爲零的字符串,則返回 '.',表示當前工作目錄。

“平臺特定的分隔符”:

  windows下文件路徑分隔符使用的是"\"

  Linux下文件路徑分隔符使用的是"/"

“path片段”:即是說,該方法接收的是多個路徑的部分或全部,然後簡單將其拼接。

“規範化”:顧名思義,如果你給出的路徑片段中任一路徑片段不是一個字符串,則拋出TypeError。

我們來舉個例子:
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf'
這裏需要注意:如果路徑中出現"..",那麼它前面的路徑片段將被丟失。
path.resolve() 方法會把一個路徑或路徑片段的序列解析爲一個絕對路徑。

給定的路徑的序列是從右往左被處理的,後面每個 path 被依次解析,直到構造完成一個絕對路徑。 例如,給定的路徑片段的序列爲:/foo、/bar、baz,則調用 path.resolve('/foo', '/bar', 'baz') 會返回 /bar/baz。

如果處理完全部給定的 path 片段後還未生成一個絕對路徑,則當前工作目錄會被用上。

生成的路徑是規範化後的,且末尾的斜槓會被刪除,除非路徑被解析爲根目錄。

長度爲零的 path 片段會被忽略。

如果沒有傳入 path 片段,則 path.resolve() 會返回當前工作目錄的絕對路徑。

path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'

path.resolve('/foo/bar', '/tmp/file/');
// 返回: '/tmp/file'

path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 如果當前工作目錄爲 /home/myself/node,
// 則返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'

總結一下:path.join只是簡單的將路徑片段進行拼接,並規範化生成一個路徑,而path.resolve則一定會生成一個絕對路徑,相當於執行cd操作。

2、file 操作 demo

const fs = require('fs')
const path = require('path')

const fileName = path.resolve(__dirname, './data.txt')

//1、一次性讀取文件內容
function test_read() {
    fs.readFile(fileName, (err, data) => {
        if (err) {
            console.log(err)
        } else {
            console.log(data.toString())
        }
    });
}

//2、一次性寫入文件
function test_write() {
    const content = '這是寫入的內容\n';
    const opt = {
        flag: 'a' //追加寫入 覆蓋用'w'
    };
    fs.writeFile(fileName, content, opt, err => {
        if (err) console.log(err)
    })
}

//3、判斷文件是否存在
function test_exist() {
    fs.exists(fileName, exists => console.log(exists))
}

test_read();
test_exist();

3、stream 操作 demo

const path = require('path');
const fs = require('fs');

//1、測試標準輸入輸出
function test_std() {
    process.stdin.pipe(process.stdout)
    const http = require('http');
    const server = http.createServer((req, res) => {
        req.pipe(res)
    })
    server.listen(8000)
}

//2、測試stream複製文件
function test_copy() {
    let aPath = path.resolve(__dirname, 'a.txt');
    let bPath = path.resolve(__dirname, 'b.txt');
    let cc = path.join(__dirname, 'b.txt');

    console.log(aPath)
    console.log(bPath)
    console.log(cc)


    let readStream = fs.createReadStream(aPath);
    let writeStream = fs.createWriteStream(bPath);
    readStream.pipe(writeStream);

    readStream.on('data', chunk => {
        console.log('copy :', chunk.toString())//一點點的讀取
    })

    readStream.on('end', () => {
        console.log('copy done')
    })
}

//3、測試stream讀取file
function test_read() {
    const http = require('http');
    const server = http.createServer((req, res) => {
        const fileName = path.resolve(__dirname, './data.txt');
        let readStream = fs.createReadStream(fileName);
        readStream.pipe(res)
    })
    server.listen(8000)
}

//4、測試stream創建並寫入文件
function test_write() {
    let c = path.resolve(__dirname, 'c.txt');
    let writeStream = fs.createWriteStream(c);
    writeStream.write('還是返回肯定是減肥', error => {
        console.log(error)
    })
}

//5、測試 readline
function test_readline() {
    let filePath = path.resolve(__dirname, 'c.txt');
    const readline = require('readline')
    //創建readStream
    let readStream = fs.createReadStream(filePath);

    //創建readline 對象
    let rl = readline.createInterface({input: readStream});

    //逐行讀取
    let count = 0;
    rl.on('line', data => {
        console.log(data)
        count++;
    })

    //監聽讀取完成
    rl.on('close', args => {
        console.log(`總共有${count}行`)
    })
}

// test_std();
// test_copy();
// test_read();
// test_write();
test_readline();

4、封裝

const path = require('path');
const fs = require('fs');


function createWriteStream(fileName) {
    let logPath = path.resolve(__dirname, '../../logs', fileName);
    return fs.createWriteStream(logPath, {flags: 'a'});
}

const accessWs = createWriteStream('access.log');
const errorWs = createWriteStream('error.log');
const eventWs = createWriteStream('event.log');


//寫日誌
function log(writeStream, logContent) {
    writeStream.write(logContent + '\n')
}

function accessLog(logContent) {
    log(accessWs, logContent);
}

function errorLog(logContent) {
    log(errorWs, logContent);
}

function eventLog(logContent) {
    log(eventWs, logContent);
}

//測試
accessLog(`-- ${Date.now()}`)

module.exports = {accessLog, errorLog, eventLog}

十三、crontab 拆分日誌

1、腳本

copy.sh

#!/bin/sh
cd [路徑]/myblog-simple/logs
cp access.log $(date +%Y-%m-%d).access.log
echo "" > access.log #清空

2、創建定時任務

crontab -e #創建任務 
0 0 0 * * * sh copy.sh
crontab -l #查看任務

十四、xss攻擊防護

1、 安裝

yarn add xss 

2、使用

const xss = require('xss');

let content = `<script>window.alert('sd')</script>`;

console.log(xss(content));

結果:

&lt;script&gt;window.alert('sd')&lt;/script&gt;

十五、nodejs 加密數據

const crypto = require('crypto');

//密匙
const SECRET_KEY = 'sadasd_dsads2';

//md5加密
function md5(content) {
    let md5 = crypto.createHash('md5');
    return md5.update(content).digest('hex');
}


//加密函數
function genPassword(password) {
    const str = `password=${password}&key=${SECRET_KEY}`; //就是md5加鹽
    return md5(str);
}


//測試
console.log(genPassword('12324'));

十六、總結

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章