主頁 > 企業開發 > Three.js 進階之旅:物理效果-3D乒乓球小游戲 🏓

Three.js 進階之旅:物理效果-3D乒乓球小游戲 🏓

2023-03-21 10:55:42 企業開發

宣告:本文涉及圖文和模型素材僅用于個人學習、研究和欣賞,請勿二次修改、非法傳播、轉載、出版、商用、及進行其他獲利行為,

摘要

本文在專欄上一篇內容《Three.js 進階之旅:物理效果-碰撞和聲音》的基礎上,將使用新的技術堆疊 React Three FiberCannon.js 來實作一個具有物理特性的小游戲,通過本文的閱讀,你將學習到的知識點包括:了解什么是 React Three Fiber 及它的相關生態、使用 React Three Fiber 搭建基礎三維場景、如何使用新技術堆疊給場景中物件的添加物理特性等,最后利用上述知識點,將開發一個簡單的乒乓球小游戲,

效果

在正式學習之前,我們先來看看本文示例最終實作效果:頁面主體內容是一個手握乒乓球拍的模型和一個乒乓球 ??,對球拍像現實生活中一樣進行顛球施力操作,乒乓球可以在球拍上彈起,乒乓球彈起的高度隨著施加在球拍上的力的大小的變化而變化,球拍中央顯示的是連續顛球次數 5??,當乒乓球從球拍掉落時一局游戲結束,球拍上的數字歸零 0?? ,快來試試你一次可以顛多少個球吧 ??

打開以下鏈接,在線預覽效果,大屏訪問效果更佳,

  • ????? 在線預覽地址:https://dragonir.github.io/physics-pingpong/

本專欄系列代碼托管在 Github 倉庫【threejs-odessey】,后續所有目錄也都將在此倉庫中更新

?? 代碼倉庫地址:[email protected]:dragonir/threejs-odessey.git

原理

React-Three-Fiber

React Three Fiber 是一個基于 Three.jsReact 渲染器,簡稱 R3F,它像是一個配置器,把 Three.js 的物件映射為 R3F 中的組件,以下是一些相關鏈接:

  • 倉庫: https://github.com/pmndrs/react-three-fiber
  • 官網: https://docs.pmnd.rs/react-three-fiber/getting-started/introduction
  • 示例: https://docs.pmnd.rs/react-three-fiber/getting-started/examples

特點

  • 使用可重用的組件以宣告方式構建動態場景圖,使 Three.js 的處理變得更加輕松,并使代碼庫更加整潔,這些組件對狀態變化做出反應,具有開箱即用的互動性,
  • Three.js 中所有內容都能在這里運行,它不針對特定的 Three.js 版本,也不需要更新以修改,添加或洗掉上游功能,
  • 渲染性能與 Three.jsGPU 相仿,組件參與 React 之外的 render loop 時,沒有任何額外開銷,

React Three Fiber 比較繁瑣,我們可以寫成 R3F 或簡稱為 Fiber,讓我們從現在開始使用 R3F 吧,

生態系統

R3F 有充滿活力的生態系統,包括各種庫、輔助工具以及抽象方法:

  • @react-three/drei – 有用的輔助工具,自身就有豐富的生態
  • @react-three/gltfjsx – 將 GLTFs 轉換為 JSX 組件
  • @react-three/postprocessing – 后期處理效果
  • @react-three/test-renderer – 用于在 Node 中進行單元測驗
  • @react-three/flexreact-three-fiberflex 盒子布局
  • @react-three/xrVR/AR 控制器和事件
  • @react-three/csg – 構造物體幾何
  • @react-three/rapier – 使用 Rapier3D 物理引擎
  • @react-three/cannon – 使用 Cannon3D 物理引擎
  • @react-three/p2 – 使用 P22D 物理引擎
  • @react-three/a11y – 可訪問工具
  • @react-three/gpu-pathtracer – 真實的路徑追蹤
  • create-r3f-app nextnextjs 啟動器
  • lamina – 基于 shader materials 的圖層
  • zustand – 基于 flux 的狀態管理
  • jotai – 基于 atoms 的狀態管理
  • valtio – 基于 proxy 的狀態管理
  • react-spring – 一個 spring-physics-based 的影片庫
  • framer-motion-3dframer motion,一個很受歡迎的影片庫
  • use-gesture – 滑鼠/觸摸手勢
  • leva – 創建 GUI 控制器
  • maath – 數學輔助工具
  • miniplexECS 物體管理系統
  • composer-suite – 合成著色器、粒子、特效和游戲機制、

安裝

npm install three @react-three/fiber

第一個場景

在一個新建的 React 專案中,我們通過以下的步驟使用 R3F 來創建第一個場景,

初始化Canvas

首先,我們從 @react-three/fiber 引入 Canvas 元素,將其放到 React 樹中:

import ReactDOM from 'react-dom'
import { Canvas } from '@react-three/fiber'

function App() {
  return (
    <div id="canvas-container">
      <Canvas />
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))

Canvas 組件在幕后做了一些重要的初始化作業:

  • 它初始化了一個場景 Scene 和一個相機 Camera,它們都是渲染所需的基本模塊,
  • 它在頁面每一幀更新中都渲染場景,我們不需要再到頁面重繪方法中回圈呼叫渲染方法,

?? Canvas 大小回應式自適應于父節點,我們可以通過改變父節點的寬度和高度來控制渲染場景的尺寸大小,

添加一個Mesh組件

為了真正能夠在場景中看到一些物體,現在我們添加一個小寫的 <mesh /> 元素,它直接等效于 new THREE.Mesh()

<Canvas>
  <mesh />

?? 可以看到我們沒有特地去額外引入mesh組件,我們不需要引入任何元素,所有Three.js中的物件都將被當作原生的JSX元素,就像在 ReactDom 中寫 <div /><span /> 元素一樣,R3F Fiber組件的通用規則是將Three.js中的它們的名字寫成駝峰式的DOM元素即可,

一個 MeshThree.js 中的基礎場景物件,需要給它提供一個幾何物件 geometry 以及一個材質 material 來代表一個三維空間的幾何形狀,我們將使用一個 BoxGeometryMeshStandardMaterial 來創建一個新的網格 Mesh,它們會自動關聯到它們的父節點,

<Canvas>
  <mesh>
    <boxGeometry />
    <meshStandardMaterial />
  </mesh>

上述代碼和以下 Three.js 代碼是等價的:

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)

const renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
document.querySelector('#canvas-container').appendChild(renderer.domElement)

const mesh = new THREE.Mesh()
mesh.geometry = new THREE.BoxGeometry()
mesh.material = new THREE.MeshStandardMaterial()

scene.add(mesh)

function animate() {
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
}

animate()

建構式引數

根據 BoxGeometry 的檔案,我們可以選擇給它傳遞三個引數:widthlengthdepth

new THREE.BoxGeometry(2, 2, 2)

為了實作相同的功能,我們可以在 R3F 中使用 args 屬性,它總是接受一個陣列,其專案表示建構式引數:

<boxGeometry args={[2, 2, 2]} />
添加光源

接著,我們通過像下面這樣添加光源組件來為我們的場景添加一些光線,

<Canvas>
  <ambientLight intensity={0.1} />
  <directionalLight color="red" position={[0, 0, 5]} />

屬性

這里介紹關于 R3F 的最后一個概念,即 React 屬性是如何在 Three.js 物件中作業的,當你給一個 Fiber 組件設定任意屬性時,它將對 Three.js 設定一個相同名字的屬性,我們關注到 ambientLight 上,由它的檔案可知,我們可以選擇 colorintensity 屬性來初始化它:

<ambientLight intensity={0.1} />

等價于

const light = new THREE.AmbientLight()
light.intensity = 0.1

快捷方法

Three.js 中對于很多屬性的設定如 colorsvectors 等都可以使用 set() 方法進行快捷設定:

const light = new THREE.DirectionalLight()
light.position.set(0, 0, 5)
light.color.set('red')

JSX 中也是相同的:

<directionalLight position={[0, 0, 5]} color="red" />
結果
<Canvas>
  <mesh>
    <boxBufferGeometry />
    <meshBasicMaterial color="#03c03c" />
  </mesh>
  <ambientLight args={[0xff0000]} intensity={0.1} />
  <directionalLight position={[0, 0, 5]} intensity={0.5} />
</Canvas>

查看React Three Fiber完整API檔案

實作

到這里,我們已經掌握了 R3F 的基本知識,我們再結合專欄上篇關于物理特性的內容,來實作如文章開頭介紹的乒乓球 ?? 小游戲,

?? 本文乒乓球小游戲基礎版及乒乓球三維模型資源來源于R3F官網示例,

〇 搭建頁面基本結構

首先,我們創建一個 Experience 檔案作為渲染三維場景的組件,并在其中添加 Canvas 組件搭建基本頁面結構,

import { Canvas } from "@react-three/fiber";

export default function Experience() {
  return (
    <>
      <Canvas></Canvas>
    </>
  );
}

① 場景初始化

接著我們開啟 Canvas 的陰影并設定相機引數,然后添加環境光 ambientLight 和點光源 pointLight 兩種光源:

<Canvas
  shadows
  camera={{ fov: 50, position: [0, 5, 12] }}
>
  <ambientLight intensity={.5} />
  <pointLight position={[-10, -10, -10]} />
</Canvas>

如果需要修改 Canvas 的背景色,可以在其中添加一個 color 標簽并設定引數 attachbackground,在 args 引數中設定顏色即可,

<Canvas>
  <color attach="background" args={["lightgreen"]} />
</Canvas>

② 添加輔助工具

接著,我們在頁面頂部引入 Perf,它是 R3F 生態中查看頁面性能的組件,它的功能和 Three.jsstats.js 是類似的,像下面這樣添加到代碼中設定它的顯示位置,頁面對應區域就會出現可視化的查看工具,在上面可以查看 GPUCPUFPS 等性能引數,

如果想使用網格作為輔助線或用作裝飾,可以使用 gridHelper 組件,它支持配置 positionrotationargs 等引數,

import { Perf } from "r3f-perf";

export default function Experience() {
  return (
    <>
      <Canvas>
        <Perf position="top-right" />
        <gridHelper args={[50, 50, '#11f1ff', '#0b50aa']} position={[0, -1.1, -4]} rotation={[Math.PI / 2.68, 0, 0]} />
      </Canvas>
    </>
  );
}

③ 創建乒乓球和球拍

我們創建一個名為 PingPong.jsx 的乒乓球組件檔案,然后在檔案頂部引入以下依賴,其中 PhysicsuseBoxusePlaneuseSphere 用于創建物理世界;useFrame 是用來進行頁面影片更新的 hook,它將在頁面每幀重繪時執行,我們可以在它里面執行一些影片函式和更新控制器,相當于 Three.js 中用原生實作的 requestAnimationFrameuseLoader 用于加載器的管理,使用它更方便進行加載錯誤管理和回呼方法執行;lerp 是一個插值運算函式,它可以計算某一數值到另一數值的百分比,從而得出一個新的數值,常用于移動物體、修改透明度、顏色、大小、模擬影片等,

import { Physics, useBox, usePlane, useSphere } from "@react-three/cannon";
import { useFrame, useLoader } from "@react-three/fiber";
import { Mesh, TextureLoader } from "three";
import { GLTFLoader } from "three-stdlib/loaders/GLTFLoader";
import lerp from "lerp";

創建物理世界

然后創建一個 PingPong 類,在其中添加 <Physics> 組件來創建物理世界,像直接使用 Cannon.js 一樣,可以給它設定 iterationstolerancegravityallowSleep 等引數來分別設定物理世界的迭代次數、容錯性、引力以及是否支持進入休眠狀態等,然后在其中添加一個平面幾何體和一個平面剛體 ContactGround

function ContactGround() {
  const [ref] = usePlane(
    () => ({
      position: [0, -10, 0],
      rotation: [-Math.PI / 2, 0, 0],
      type: "Static",
    }),
    useRef < Mesh > null
  );
  return <mesh ref={ref} />;
}

export default function PingPong() {
  return (
    <>
      <Physics
        iterations={20}
        tolerance={0.0001}
        defaultContactMaterial={{
          contactEquationRelaxation: 1,
          contactEquationStiffness: 1e7,
          friction: 0.9,
          frictionEquationRelaxation: 2,
          frictionEquationStiffness: 1e7,
          restitution: 0.7,
        }}
        gravity={[0, -40, 0]}
        allowSleep={false}
      >
        <mesh position={[0, 0, -10]} receiveShadow>
          <planeGeometry args={[1000, 1000]} />
          <meshPhongMaterial color="#5081ca" />
        </mesh>
        <ContactGround />
      </Physics>
    </>
  );
}

創建乒乓球

接著,我們創建一個球體類 Ball,在其中添加球體 ?? ,可以使用前面介紹的 useLoader 來管理它的貼圖加載,為了方便觀察到乒乓球的轉動情況,貼圖中央加了一個十字交叉圖案 ?,然后將其放在 <Physics> 標簽下,

function Ball() {
  const map = useLoader(TextureLoader, earthImg);
  const [ref] = useSphere(
    () => ({ args: [0.5], mass: 1, position: [0, 5, 0] }),
    useRef < Mesh > null
  );
  return (
    <mesh castShadow ref={ref}>
      <sphereGeometry args={[0.5, 64, 64]} />
      <meshStandardMaterial map={map} />
    </mesh>
  );
}

export default function PingPong() {
  return (
    <>
      <Physics>
        { /* ... */ }
        <Ball />
      </Physics>
    </>
  );
}

創建球拍

球拍 ?? 采用的是一個 glb 格式的模型,在 Blender 中我們可以看到模型的樣式和詳細的骨骼結構,對于模型的加載,我們同樣使用 useLoader 來管理,此時的加載器需要使用 GLTFLoader

我們創建一個 Paddle 類并將其添加到 <Physics> 標簽中,在這個類中我們實作模型加載,模型加載完成后系結骨骼,并在 useFrame 頁面重繪方法中,根據滑鼠所在位置更新乒乓球拍模型的位置 position,并根據是否一開始游戲狀態以及滑鼠的位置來更新球拍的 x軸y軸 方向的 rotation 值,

function Paddle() {
  const { nodes, materials } = useLoader(
    GLTFLoader,
    '/models/pingpong.glb',
  );
  const model = useRef();
  const [ref, api] = useBox(() => ({
    type: 'Kinematic',
    args: [3.4, 1, 3.5],
  }));
  const values = useRef([0, 0]);
  useFrame((state) => {
    values.current[0] = lerp(
      values.current[0],
      (state.mouse.x * Math.PI) / 5,
      0.2
    );
    values.current[1] = lerp(
      values.current[1],
      (state.mouse.x * Math.PI) / 5,
      0.2
    );
    api.position.set(state.mouse.x * 10, state.mouse.y * 5, 0);
    api.rotation.set(0, 0, values.current[1]);
    if (!model.current) return;
    model.current.rotation.x = lerp(
      model.current.rotation.x,
      started ? Math.PI / 2 : 0,
      0.2
    );
    model.current.rotation.y = values.current[0];
  });

  return (
    <mesh ref={ref} dispose={null}>
      <group
        ref={model}
        position={[-0.05, 0.37, 0.3]}
        scale={[0.15, 0.15, 0.15]}
      >
        <group rotation={[1.88, -0.35, 2.32]} scale={[2.97, 2.97, 2.97]}>
          <primitive object={nodes.Bone} />
          <primitive object={nodes.Bone003} />
          { /* ... */ }
          <skinnedMesh
            castShadow
            receiveShadow
            material={materials.glove}
            material-roughness={1}
            geometry={nodes.arm.geometry}
            skeleton={nodes.arm.skeleton}
          />
        </group>
        <group rotation={[0, -0.04, 0]} scale={[141.94, 141.94, 141.94]}>
          <mesh
            castShadow
            receiveShadow
            material={materials.wood}
            geometry={nodes.mesh.geometry}
          />
          { /* ... */ }
        </group>
      </group>
    </mesh>
  );
}

到這里,我們已經實作乒乓球顛球的基本功能了 ??

顛球計數

為了顯示每次游戲可以顛球的次數,現在我們在乒乓球拍中央加上數字顯示 5?? ,我們可以像下面這樣創建一個 Text 類,在檔案頂部引入 TextGeometryFontLoaderfontJson 作為字體幾何體、字體加載器以及字體檔案,添加一個 geom 作為創建字體幾何體的方法,當 count 狀態值發生變化時,實時更新創建字體幾何體模型,

import { useMemo } from "react";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import fontJson from "../public/fonts/firasans_regular.json";

const font = new FontLoader().parse(fontJson);
const geom = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].map(
  (number) => new TextGeometry(number, { font, height: 0.1, size: 5 })
);

export default function Text({ color = 0xffffff, count, ...props }) {
  const array = useMemo(() => [...count], [count]);
  return (
    <group {...props} dispose={null}>
      {array.map((char, index) => (
        <mesh
          position={[-(array.length / 2) * 3.5 + index * 3.5, 0, 0]}
          key={index}
          geometry={geom[parseInt(char)]}
        >
          <meshBasicMaterial color={color} transparent opacity={0.5} />
        </mesh>
      ))}
    </group>
  );
}

然后將 Text 字體類放入球拍幾何體中,其中 count 欄位需要在物理世界中剛體發生碰撞時進行更新,該方法加載下節內容添加碰撞音效時一起實作,

function Paddle() {
  return (
    <mesh ref={ref} dispose={null}>
      <group ref={model}>
        { /* ... */ }
        <Text
          rotation={[-Math.PI / 2, 0, 0]}
          position={[0, 1, 2]}
          count={count.toString()}
        />
      </group>
    </mesh>
  );
}

④ 頁面裝飾

到這里,整個小游戲的全部流程都開發完畢了,現在我們來加一些頁面提示語、顛球時的碰撞音效,頁面的光照效果等,使 3D 場景看起來更加真實,

音效

實作音效 ?? 前,我們先像下面這樣添加一個狀態管理器 ?? ,來進行頁面全域狀態的管理,zustand 是一個輕量級的狀態管理庫;_.clamp(number, [lower], upper) 用于回傳限制在 lowerupper 之間的值;pingSound 是需要播放的音頻檔案,我們在其中添加一個 pong 方法用來更新音效顛球計數,添加一個 reset 方法重置顛球數字,count 欄位表示每次的顛球次數,welcome 表示是否在歡迎界面,

import create from "zustand";
import clamp from "lodash-es/clamp";
import pingSound from "/medias/ping.mp3";

const ping = new Audio(pingSound);

export const useStore = create((set) => ({
  api: {
    pong(velocity) {
      ping.currentTime = 0;
      ping.volume = clamp(velocity / 20, 0, 1);
      ping.play();
      if (velocity > 4) set((state) => ({ count: state.count + 1 }));
    },
    reset: (welcome) =>
      set((state) => ({ count: welcome ? state.count : 0, welcome })),
  },
  count: 0,
  welcome: true,
}));

然后我們可以在上述 Paddle 乒乓球拍類中像這樣在物體發生碰撞時觸發 pong 方法:

function Paddle() {
  {/* ... */}
  const [ref, api] = useBox(() => ({
    type: "Kinematic",
    args: [3.4, 1, 3.5],
    onCollide: (e) => pong(e.contact.impactVelocity),
  }));
}

光照

為了是場景更加真實,我們可以開啟 Canvas 的陰影,然后添加多種光源 ?? 來優化場景,如 spotLight 就能起到視覺聚焦的作用,

<Canvas
  shadows
  camera={{ fov: 50, position: [0, 5, 12] }}
>
  <ambientLight intensity={.5} />
  <pointLight position={[-10, -10, -10]} />
  <spotLight
    position={[10, 10, 10]}
    angle={0.3}
    penumbra={1}
    intensity={1}
    castShadow
    shadow-mapSize-width={2048}
    shadow-mapSize-height={2048}
    shadow-bias={-0.0001}
  />
  <PingPong />
</Canvas>

提示語

為了提升小游戲的用戶體驗,我們可以添加一些頁面文字提示來指引使用者和提升頁面視覺效果,需要注意的是,這些額外的元素不能添加到 <Canvas /> 標簽內哦 ??

const style = (welcome) => ({
  color: '#000000',
  display: welcome ? 'block' : 'none',
  fontSize: '1.8em',
  left: '50%',
  position: "absolute",
  top: 40,
  transform: 'translateX(-50%)',
  background: 'rgba(255, 255, 255, .2)',
  backdropFilter: 'blur(4px)',
  padding: '16px',
  borderRadius: '12px',
  boxShadow: '1px 1px 2px rgba(0, 0, 0, .2)',
  border: '1px groove rgba(255, 255, 255, .2)',
  textShadow: '0px 1px 2px rgba(255, 255, 255, .2), 0px 2px 2px rgba(255, 255, 255, .8), 0px 2px 4px rgba(0, 0, 0, .5)'
});

<div style={style(welcome)}>?? 點擊任意區域開始顛球</div>

?? 原始碼地址: https://github.com/dragonir/threejs-odessey

總結

本文中主要包含的知識點包括:

  • 了解什么是 React Three Fiber 及相關生態,
  • React Three Fiber 基礎入門,
  • 使用 React Three Fiber 開發一個乒乓球小游戲,學會如何場景構建、模型加載、物理世界關聯、全域狀態管理等,

想了解其他前端知識或其他未在本文中詳細描述的Web 3D開發技術相關知識,可閱讀我往期的文章,如果有疑問可以在評論中留言,如果覺得文章對你有幫助,不要忘了一鍵三連哦 ??

附錄

  • [1]. ?? Three.js 打造繽紛夏日3D夢中情島
  • [2]. ?? Three.js 實作炫酷的賽博朋克風格3D數字地球大屏
  • [3]. ?? Three.js 實作2022冬奧主題3D趣味頁面,含冰墩墩
  • [4]. ?? Three.js 實作3D開放世界小游戲:阿貍的多元宇宙
  • [5]. ?? 掘金1000粉!使用Three.js實作一個創意紀念頁面
  • ...
  • 【Three.js 進階之旅】系列專欄訪問 ??
  • 更多往期【3D】專欄訪問 ??
  • 更多往期【前端】專欄訪問 ??

參考

  • [1]. React Three Fiber
  • [2]. threejs.org

本文作者:dragonir 本文地址:https://www.cnblogs.com/dragonir/p/17235128.html

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

標籤:其他

上一篇:uni-app開發跨平臺小程式開發的諸多坑【轉載】

下一篇:帶你看看不一樣的console.log 和BUG除錯

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