主頁 > 企業開發 > 低代碼 系列 —— 中后臺集成低代碼預研

低代碼 系列 —— 中后臺集成低代碼預研

2023-04-11 08:18:03 企業開發

其他章節請看:

低代碼 系列

中后臺集成低代碼預研

背景

筆者目前維護一個 react 中后臺系統(以 spug 為例),每次來了新的需求都需要前端人員重新開發,

前面我們已經對低代碼有了一定的認識,如果能通過一個可視化的配置頁面就能完成前端開發,將極大的提高前端(或后端)的效率,甚至能加快企業內部數字化(資訊化)建設,

低代碼介紹

低代碼這一概念由 Forrester 在 2014 年正式提出,低代碼,顧名思義,就是指開發者寫很少的代碼,通過低代碼平臺提供的界面、邏輯、物件、流程等可視化編排工具來完成大量的開發作業,降低軟體開發中的不確定性和復雜性,實作軟體的高效構建,無需重復傳統的手動編程,同時兼顧業務人員和專業開發人員的更多參與,

零代碼屬于低代碼平臺的一種,不提供或者僅支持有限的編程擴展能力,技術門檻低,應用場景有限,

目標

最優 稍次
通過低代碼平臺配置系統所有前端頁面 通過低代碼平臺配置系統大部分前端頁面

預研產品

amis

amis 是百度的一個低代碼前端框架,它使用 JSON 配置來生成頁面,可以減少頁面開發作業量,極大提升效率,開源免費,github Star 13.4k,

包含兩個專案:amis 和 amis-editor(前些天已開源),amis-editor 通過可視化形式生成頁面,畫原型的功夫就將前端頁面給開發好了,最后生成該頁面的配置(一個json),該配置放入 amis 決議出來就是一個前端頁面,

amis 在線編輯器如下:

Tip: amis 更過介紹請看這里、amis api

愛速搭

愛速搭是百度智能云推出的低代碼開發平臺,它靈活性強,對開發者友好,在百度內部大規模使用,有超過 4w 內部頁面是基于它制作的,是百度內部中臺系統的核心基礎設施,支持私有部署,收費

Tip: amis 是愛速搭團隊開源的前端低代碼框架,愛速搭應用中的頁面都是基于 amis 渲染的,同時愛速搭平臺自身的絕大部分頁面也是基于 amis 開發 —— 愛速搭與amis

lowcode-engine

阿里低代碼引擎(lowcode-engine)是一款為低代碼平臺開發者提供的,具備強大定制擴展能力的低代碼設計器研發框架,免費

Tip: 前面筆者也稍微實作了一個簡單的可視化編輯器,有些麻煩,也有很多不足,真實場景傾向使用成熟的編輯器

釘釘宜搭

釘釘宜搭是阿里巴巴自研的低代碼應用開發平臺,基于阿里云的云基礎設施和釘釘的企業數字化作業系統,為每個組織提供低門檻、高效率的數字化業務應用生產新模式,在宜搭上生產的每個應用天然具備互聯互通、資料驅動、安全可控的特點,收費

在宜搭模版市場提供了一些免費應用模版,只需選擇一個模版修改個別文案,一分鐘就能搭建一款專屬應用

方案概要

市面上確實存在幫助企業加快數字化建設的低代碼平臺,通過該平臺能較快的搭建各種系統,但通常是收費的,

通過各類低代碼產品的預研,也結合筆者當前作業需求:免費內網部署靈活),目標求其次:通過低代碼平臺配置系統大部分前端頁面,

方案篩選:

  • amis vs 愛速搭:amis 免費
  • amis vs lowcode-engine: amis 更全,包含編輯器和渲染器(決議 json 成前端頁面),而 lowcode-engine 只是一個編輯器,倘若需要自建一個低代碼平臺, lowcode-engine 是一個不錯的選擇

最終方案:中后臺系統(spug) + amis + amis-editor(開源、免費),就像這樣:

graph LR A[[amis editor]]-- 配置頁面生成 --> B{{json}}-- 傳輸 --> C[[amis]] -- 決議JSON渲染 --> 頁面
  • amis-editor 配置頁面,生成 json
  • amis 通過 json 渲染出頁面
  • spug 集成 amis

方案可行性

通過 amis-editor 可視化操作快速創建頁面,然后將配置放入 amis 中決議,實作大部分前端頁面的可視化生成,

介面資料

本地啟動一個 node 服務,用于模擬介面資料,

使用其他服務也可以,只要發送請求能回傳資料(資料參考 amis 官網,直接使用 amis 官網的介面報跨域失敗),就像這樣:

node 服務

初始化專案 local-mock:

$ mkdir local-mock
$ cd local-mock
// 初始化專案
$ npm init -y

修改如下 package.json:

{
  "name": "local-mock",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.2",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^2.0.22"
  }
}

新建 node.js(注:允許來自 http://localhost 的跨域請求):

// node.js

var express = require('express');
var app = express();

// 跨域參考:https://blog.csdn.net/gdutRex/article/details/103636581
var allowCors = function (req, res, next) {
    // 注:筆者使用 `*` 仍報跨域問題,修改為請求地址(`http://localhost`)即可,
    res.header('Access-Control-Allow-Origin', 'http://localhost');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type,lang,sfopenreferer ');
    res.header('Access-Control-Allow-Credentials', 'true');
    next();
};

//使用跨域中間件
app.use(allowCors);

// mock資料來自 amis 官網示例:https://aisuda.bce.baidu.com/amis/zh-CN/components/crud
const data1 = {"status":0,"msg":"ok","data":{"count":171,"rows":[{"engine":"Gecko - tuhzbk","browser":"Camino 1.0","platform":"OSX.2+","version":"1.8","grade":"A","id":11},{"engine":"Gecko - aias9l","browser":"Camino 1.5","platform":"OSX.3+","version":"1.8","grade":"A","id":12},{"engine":"Gecko - s72lo","browser":"Netscape 7.2","platform":"Win 95+ / Mac OS 8.6-9.2","version":"1.7","grade":"A","id":13},{"engine":"Gecko - 1uegwbc","browser":"Netscape Browser 8","platform":"Win 98SE+","version":"1.7","grade":"A","id":14},{"engine":"Gecko - tjtajk","browser":"Netscape Navigator 9","platform":"Win 98+ / OSX.2+","version":"1.8","grade":"A","id":15},{"engine":"Gecko - ux0rsf","browser":"Mozilla 1.0","platform":"Win 95+ / OSX.1+","version":"1","grade":"A","id":16},{"engine":"Gecko - a3ae5r","browser":"Mozilla 1.1","platform":"Win 95+ / OSX.1+","version":"1.1","grade":"A","id":17},{"engine":"Gecko - 55daeh","browser":"Mozilla 1.2","platform":"Win 95+ / OSX.1+","version":"1.2","grade":"A","id":18},{"engine":"Gecko - eh2p99","browser":"Mozilla 1.3","platform":"Win 95+ / OSX.1+","version":"1.3","grade":"A","id":19},{"engine":"Gecko - f6yo9k","browser":"Mozilla 1.4","platform":"Win 95+ / OSX.1+","version":"1.4","grade":"A","id":20}]}}
const data2 = { "status": 0, "msg": "ok" }

// 查詢
app.get('/amis/api/mock2/', function (req, res) {
    res.end(JSON.stringify(data1));
})

// 新增
app.post('/amis/api/mock2/', function (req, res) {
    res.end(JSON.stringify(data2));
})

// 監聽3000埠
var server = app.listen(3020, function () {
    console.log('listening at =====> http://127.0.0.1:3020...');
});

編輯器

下載 amis-editor-demo,通過 npm i 安裝依賴,然后 npm run dev 本地啟動編輯器:

Administrator@3L-WK-10 MINGW64 /e/amis-editor-demo-master (master)
$ npm run dev

> [email protected] dev E:\amis-editor-demo-master
> amis dev


                             _/
    _/_/_/  _/_/_/  _/_/          _/_/_/
 _/    _/  _/    _/    _/  _/  _/_/
_/    _/  _/    _/    _/  _/      _/_/
 _/_/_/  _/    _/    _/  _/  _/_/_/


當前版本:v3.1.8.

- [amis]開啟除錯模式...
<i> [webpack-dev-middleware] wait until bundle finished
assets by path *.js 66.8 MiB
  assets by chunk 28.6 MiB (id hint: vendors) 53 assets
  + 61 assets
assets by info 4.13 MiB [immutable]
  assets by chunk 2.92 MiB (auxiliary name: editor) 17 assets
  + 5 assets
assets by path *.css 5.07 MiB
  assets by chunk 224 KiB (id hint: vendors) 2 assets
  asset index.css 2.98 MiB [emitted] (name: index)
  asset editor.css 1.87 MiB [emitted] (name: editor)
assets by path *.html 1.31 KiB
  asset editor.html 674 bytes [emitted]
  asset index.html 672 bytes [emitted]
Entrypoint index 13.7 MiB (4.06 MiB) = index.css 2.98 MiB index.js 10.7 MiB 21 auxiliary assets
Entrypoint editor 12.6 MiB (2.92 MiB) = editor.css 1.87 MiB editor.js 10.8 MiB 17 auxiliary assets
runtime modules 1.06 MiB 652 modules
orphan modules 3.34 MiB (javascript) 4.13 MiB (asset) [orphan] 106 modules
javascript modules 31.1 MiB
  modules by path ./node_modules/ 31.1 MiB 3639 modules
  modules by path ./src/ 38.4 KiB 22 modules
css modules 3.15 MiB
  modules by path ./node_modules/monaco-editor/esm/vs/ 138 KiB 68 modules
  modules by path ./node_modules/amis/ 2.65 MiB 3 modules
  modules by path ./node_modules/@fortawesome/fontawesome-free/css/*.css 113 KiB 2 modules
  + 3 modules
json modules 1.93 MiB
  ./node_modules/amis/schema.json 1.9 MiB [built] [code generated]
  ./node_modules/entities/lib/maps/entities.json 28.4 KiB [built] [code generated]
webpack 5.76.3 compiled successfully in 37081 ms
√ [amis]除錯模式已開啟!
> Listening at http://localhost:80

當前運行腳本:
 http://localhost:80/index.js
當前運行樣式[可能不存在]:
http://localhost:80/index.css
(node:10788) UnhandledPromiseRejectionWarning: Error: Exited with code 4294967295
...

輸出有點錯誤,不管它,瀏覽器訪問 http://localhost:80 即可進入編輯器頁面,

下面筆者快速演示配置一個有增加洗掉編輯查詢的頁面,就像這樣:

配置程序如下:

最后生成的配置在這里(也可直接修改):

Tip:除了編輯的url需要修改 json,其他的都可以在編輯器右側中配置,

:目前筆者將 amis-editor 作為一個單獨的專案運行,通過 npm run build 打包,打包后的 html 中出現以 https://aisuda.github.io/amis-editor-demo/demo/ 開頭的資源,引入內網是不行的,于是更改 assetsPublicPath: './' 即可指向引入打包出來的資源,目前還是有點小圖示沒有出來,可能需要更改某些地方,

// amis.config.js
build: {
    entry: { 
      index: './src/index.tsx',
      editor:  './src/mobile.tsx',
    },
    NODE_ENV: 'production',
    assetsRoot: resolve('./demo'), // 打包后的檔案絕對路徑(物理路徑)
    // assetsPublicPath: 'https://aisuda.github.io/amis-editor-demo/demo/', // 設定靜態資源的參考路徑(根域名+路徑)
    assetsPublicPath: './', // 設定靜態資源的參考路徑(根域名+路徑)
    ...
}

中后臺集成 amis

引入 amis

下載sdk.tar.gz 解壓后把 skd 檔案夾放入 spug 的 public 中,然后在單頁面中引入,就像這樣:

// spug/public.index.html

<!-- 引入 amis 的包 >
<link rel="stylesheet" href="https://www.cnblogs.com/pengjiali/archive/2023/04/10/sdk/sdk.css" />
<link rel="stylesheet" href="https://www.cnblogs.com/pengjiali/archive/2023/04/10/sdk/helper.css" />
<link rel="stylesheet" href="https://www.cnblogs.com/pengjiali/archive/2023/04/10/sdk/iconfont.css" />

<script src="https://www.cnblogs.com/pengjiali/archive/2023/04/10/sdk/sdk.js"></script>

...
<title>Spug</title>

Tip:amis 還提供了 react 的方式,也就是通過 npm 來使用,但公司分配的機器不太好,構建專案報記憶體不夠(JavaScript heap out of memory),多次嘗試(比如:在 linux(node18)中運行、調整記憶體大小 --max-old-space-size、win7 中安裝 node14/16)也未解決,只能選用 sdk 的方式,

新建頁面

新建頁面 amis A,用于將 amis-editor 的配置 json 渲染出前端頁面,相關代碼有:

  • store.js - 取得 amis-editor 的配置,這里使用 mockjs 模擬,資料就是上文編輯器創建的頁面,
// spug\src\pages\amis\store.js
import { observable,} from 'mobx';
import http from 'libs/http';

class Store {
    // 表格資料
    @observable config = {};
    @observable isFetching = false;

    fetchRecords = (path) => {
        http.get(`/api${path}/`)
            .then(res => {
                // {type: "page", title: "Hello world", body: Array(2), id: "u:7b55b5793e16", asideResizor: false, …}
                console.log('res', res)
                this.config = res;
            })
            .finally(() => this.isFetching = false)
    };
}

export default new Store()
  • index.js - 根據配置渲染頁面,也就是 amis 決議 json:
// spug\src\pages\amis\index.js
import React from 'react';
import { observer } from 'mobx-react';
import axios from 'axios';

import store from './store';
import _ from 'lodash';

window.enableAMISDebug = true
// amis 環境配置
const env = {
    theme: 'cxd',
    // 下面三個介面必須實作
    fetcher: ({
        url, // 介面地址
        method, // 請求方法 get、post、put、delete
        data, // 請求資料
        responseType,
        config, // 其他配置
        headers // 請求頭
    }) => {
        config = config || {};
        config.withCredentials = true;
        responseType && (config.responseType = responseType);

        if (config.cancelExecutor) {
            config.cancelToken = new (axios).CancelToken(
                config.cancelExecutor
            );
        }

        config.headers = headers || {};

        if (method !== 'post' && method !== 'put' && method !== 'patch') {
            if (data) {
                config.params = data;
            }
            return (axios)[method](url, config);
        } else if (data && data instanceof FormData) {
            config.headers = config.headers || {};
            config.headers['Content-Type'] = 'multipart/form-data';
        } else if (
            data &&
            typeof data !== 'string' &&
            !(data instanceof Blob) &&
            !(data instanceof ArrayBuffer)
        ) {
            data = https://www.cnblogs.com/pengjiali/archive/2023/04/10/JSON.stringify(data);
            config.headers = config.headers || {};
            config.headers['Content-Type'] = 'application/json';
        }

        return (axios)[method](url, data, config);
    },
    isCancel: (value) => {
        console.log('isCancel')
    },
    copy: (content) => {
        console.log('copy')
    }
};

function updateAmis(...options) {
    if (!document.getElementById('amisbox')) {
        return
    }
    let amis = window.amisRequire('amis/embed');
    let amisScoped = amis.embed('#amisbox', ...options);
}
@observer
class AMISComponent extends React.Component {
    componentDidMount() {
        const path = this.props.page
        // 請求對應頁面的配置
        store.fetchRecords(path)
    }

    render() {
        // 根據組態檔重新渲染頁面
        // 注:使用 lodash 的深拷貝不起作用
        updateAmis(JSON.parse(JSON.stringify(store.config)), {}, env)
        return <div id="amisbox"></div>

    }
}

class APP extends React.Component {
    componentWillUnmount() {
        // 卸載時需要清空,否則切換頁面還會顯示上個頁面
        store.config = {};
    }
    render() {
        return (
            <>
                <AMISComponent page={this.props.location.pathname} />
            </>
        );
    }
}
export default APP;

:為了讓配置變更時 amis 能重新渲染頁面,筆者使用了一個 hack 的方式:JSON.parse(JSON.stringify(store.config)),其他方法都不行(curd 存在顯示問題):Object.assign(store.config)、_.cloneDeep(store.config)、{...store.config}

Tip: 這段代碼參考 react 引入方式的 https://github.com/aisuda/amis-react-starter/blob/main/src/App.tsx,例子中是 typescript 寫法,對于暫時不支持 ts 的專案,直接將型別去除即可使用,就像這樣:

config.cancelToken = new (axios as any).CancelToken(
    config.cancelExecutor
);
// 去除 ts 的型別
config.cancelToken = new (axios).CancelToken(
    config.cancelExecutor
);
import React from 'react';
import { observer } from 'mobx-react';
import axios from 'axios';

import { render as renderAmis, ToastComponent, AlertComponent } from 'amis';
import store from './store';
import _ from 'lodash';

// amis 環境配置
const env = {
  theme: 'cxd',
  // 下面三個介面必須實作
  fetcher: ({
    url, // 介面地址
    method, // 請求方法 get、post、put、delete
    data, // 請求資料
    responseType,
    config, // 其他配置
    headers // 請求頭
  }) => {
    console.log('fetcher', method)
    config = config || {};
    config.withCredentials = true;
    responseType && (config.responseType = responseType);

    if (config.cancelExecutor) {
      config.cancelToken = new (axios).CancelToken(
        config.cancelExecutor
      );
    }

    config.headers = headers || {};

    if (method !== 'post' && method !== 'put' && method !== 'patch') {
      if (data) {
        config.params = data;
      }
      return (axios)[method](url, config);
    } else if (data && data instanceof FormData) {
      config.headers = config.headers || {};
      config.headers['Content-Type'] = 'multipart/form-data';
    } else if (
      data &&
      typeof data !== 'string' &&
      !(data instanceof Blob) &&
      !(data instanceof ArrayBuffer)
    ) {
      data = https://www.cnblogs.com/pengjiali/archive/2023/04/10/JSON.stringify(data);
      config.headers = config.headers || {};
      config.headers['Content-Type'] = 'application/json';
    }

    return (axios)[method](url, data, config);
  },
  isCancel: (value) => {
    console.log('isCancel')
  },
  copy: (content) => {
    console.log('copy')
  }
};

@observer
class AMISComponent extends React.Component {
  componentDidMount() {
    const path = this.props.page
    // 請求對應頁面的配置
    store.fetchRecords(path)
  }

  render() {
    return renderAmis(
      // store.config,
      // 使用 _.cloneDeep() 報錯
      JSON.parse(JSON.stringify(store.config)),
      {
        // props...
      },
      env
    );
  }
}

class APP extends React.Component {
  componentWillUnmount() {
    // 卸載時需要清空,否則切換頁面還會顯示上個頁面
    store.config = {};
  }
  render() {
    return (
      <>
        <ToastComponent key="toast" position={'top-right'} />
        <AlertComponent key="alert" />
        <AMISComponent page={this.props.location.pathname} />
      </>
    );
  }
}

export default APP;
放行 amis 介面

:spug 中 axios 被封裝到 http.js 中,雖然在 amis 中通過 axios 發送請求,還是會走 http.js 中的攔截器(handleResponse)

由于 amis 的資料格式和 spug 的不同,這里暫時約定有 flag:amis 的是 amis 的介面,資料不做處理,直接放行,

// http.js

import http from 'axios'
...
// response處理
function handleResponse(response) {
  // 由于 amis 的資料格式和 spug 的不同,這里暫時約定有 flag:amis(例如:{"flag": "amis", "status": 0, "msg": "ok" }) 的是amis 的介面,資料不做處理,直接放行
  const isAmis = response.data.flag === 'amis'
  if(isAmis){
    return Promise.resolve(response.data)
  }

Tip:amis 所需的資料格式和 spug 的不同,一種方法是前端來調整,建議讓后端回傳 amis 所需的資料格式,因為這是 amis 的頁面,是新功能,

node 服務

現在spug的服務介面是 3010,修改 node 服務允許其跨域:

var allowCors = function (req, res, next) {
    // 注:筆者使用 `*` 仍報跨域問題,修改為請求地址(`http://localhost`)即可,
    res.header('Access-Control-Allow-Origin', 'http://localhost:3010');
    ...
    next();
};

Tip:使用 yapi(docker 方式安裝即可) 非常方便模擬資料,也無需處理跨域,

效果

amis-editor 集成到 spug 的效果如下:

自定義組件

amis-editor 也提供了自定義組件,筆者參考自定義組件-a新建一個自定義組件-b:

實作很簡單,就是復制一份以下檔案:

-   ./renderer/MyRenderer.tsx
-   ./editor/MyRenderer.tsx

spug 中的 amis 集成該自定義組件,可以這樣做:

// 自定義組件,props 中可以拿到配置中的所有引數,比如 props.label 是 'Name'
function CustomComponent(props) {
    const { target } = props;
    let dom = React.useRef(null);
    React.useEffect(function () {
        // 從這里開始寫自定義代碼,dom.current 就是新創建的 dom 節點
        // 可以基于這個 dom 節點對接任意 JavaScript 框架,比如 jQuery/Vue 等
        dom.current.innerHTML = `<p>Hello {target}! @amis-editor</p>`
        // 而 props 中能拿到這個
    });
    return React.createElement('div', {
        ref: dom
    });
}

方案總結

中臺系統 + amis + amis-editor 此方案能通過可視化的配置實作前端頁面的開發,實作所見即所得的效果,

graph LR A[[amis editor]]-- 配置頁面生成 --> B{{json}}-- 傳輸 --> C[[amis]] -- 決議JSON渲染 --> 頁面

對于常用的頁面只需要通過可視化配置界面就能完成前端開發,

其他章節請看:

低代碼 系列

作者:彭加李
出處:https://www.cnblogs.com/pengjiali/p/17302902.html
本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連接,

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

標籤:其他

上一篇:基于SqlSugar的開發框架循序漸進介紹(26)-- 實作本地上傳、FTP上傳、阿里云OSS上傳三者合一處理

下一篇:rxjs的幾點使用心得

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