Rumah > hujung hadapan web > tutorial js > Adakah anda tahu bagaimana bahagian hadapan melaksanakan penanda air?

Adakah anda tahu bagaimana bahagian hadapan melaksanakan penanda air?

醉折花枝作酒筹
Lepaskan: 2021-07-30 16:57:50
ke hadapan
2720 orang telah melayarinya

Dalam kerja harian, kita sering menghadapi banyak data sensitif Untuk mengelakkan kebocoran data, kita perlu melakukan beberapa "pembungkusan" pada data. Tujuannya adalah untuk membuat "elemen penjenayah" yang berminat untuk membocorkan data melepaskan tingkah laku haram mereka di bawah "tekanan pendapat umum" yang teruk dan menjadikan mereka "percubaan jenayah" untuk mencapai kesan mengalahkan orang lain tanpa melawan.

Bagi kami yang bekerja di bahagian keselamatan, konsep keselamatan data telah berakar umbi dalam tulang kami Setiap teks dan setiap gambar mesti berhati-hati sama ada terdapat risiko kebocoran kebocoran adalah persoalan yang kami fikirkan. Sebagai contoh, tera air gambar adalah isu yang sering kita hadapi dalam proses kerja kita. Kerana kandungan tugas saya adalah pembangunan platform semakan, beberapa gambar berisiko sering muncul di platform semakan Memandangkan kesedaran keselamatan pengulas adalah tidak sekata, untuk mengelakkan perkara yang tidak selamat daripada berlaku, adalah perlu untuk menambah tera air. gambar-gambar daripada.

Analisis masalah

Pertama sekali, memandangkan senario perniagaan, masalah pada peringkat ini hanya membimbangkan tentang kebocoran data semasa proses semakan, kami hanya mempertimbangkan secara eksplisit tera air, yang boleh ditambahkan pada teks atau data lain yang mengenal pasti anda secara peribadi. Dengan cara ini, individu boleh dikesan berdasarkan data yang bocor Sudah tentu, fungsi yang paling penting adalah untuk mengambil langkah berjaga-jaga dan mencegah masalah sebelum ia berlaku.

Selesaikan masalah

Kaedah pelaksanaan

Terdapat banyak cara untuk melaksanakan tera air, yang boleh dibahagikan kepada Front- penanda air akhir dan penanda air bahagian belakang Kelebihan penanda air bahagian hadapan boleh diringkaskan dalam tiga mata Pertama, ia tidak menduduki sumber pelayan dan bergantung sepenuhnya pada kuasa pengkomputeran pelanggan, mengurangkan tekanan pada pelayan. Kedua, ia pantas Tidak kira pelaksanaan bahagian hadapan mana yang dilaksanakan, prestasinya lebih baik daripada bahagian belakang. Ketiga, pelaksanaannya mudah. Kelebihan terbesar melaksanakan penanda air pada bahagian belakang juga boleh diringkaskan dalam tiga perkara, iaitu keselamatan, keselamatan dan keselamatan. Zhihu dan Weibo kedua-duanya menggunakan penyelesaian tera air bahagian belakang. Walau bagaimanapun, selepas pertimbangan menyeluruh, kami masih menggunakan penyelesaian bahagian hadapan untuk melaksanakan penanda air. Yang berikut juga akan memperkenalkan secara ringkas cara nodejs melaksanakan penanda air imej bahagian belakang.

pelaksanaan nod

menyediakan tiga pakej npm Bahagian ini bukan fokus artikel kami, hanya demo ringkas disediakan.

1, gm https://github.com/aheckmann/gm 6.4k bintang

1

2

3

4

5

6

7

8

9

const fs = require('fs');

const gm = require('gm');

 

 

gm('/path/to/my/img.jpg')

.drawText(30, 20, "GMagick!")

.write("/path/to/drawing.png", function (err) {

  if (!err) console.log('done');

});

Salin selepas log masuk

Perlu memasang GraphicsMagick atau ImageMagick

2, nod-imej : https://github.com/zhangyuanwei/node-images

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

const wrap = document.querySelector('#ReactApp');

const { clientWidth, clientHeight } = wrap;

const waterHeight = 120;

const waterWidth = 180;

// 计算个数

const [columns, rows] = [~~(clientWidth / waterWidth), ~~(clientHeight / waterHeight)]

for (let i = 0; i < columns; i++) {

    for (let j = 0; j <= rows; j++) {

        const waterDom = document.createElement(&#39;div&#39;);

        // 动态设置偏移值

        waterDom.setAttribute(&#39;style&#39;, `

            width: ${waterWidth}px;

            height: ${waterHeight}px;

            left: ${waterWidth + (i - 1) * waterWidth + 10}px;

            top: ${waterHeight + (j - 1) * waterHeight + 10}px;

            color: #000;

            position: absolute`

        );

        waterDom.innerText = &#39;测试水印&#39;;

        wrap.appendChild(waterDom);

    }

}

Salin selepas log masuk

Tidak perlu memasang alat lain, ringan, dibangunkan oleh zhangyuanwei Cina, dokumentasi Cina;

3, jimp: https ://github.com/oliver-moran/jimp

Boleh digunakan dengan gifwrap untuk melaksanakan tera air gif; >1, pelaksanaan imej latar belakang Tera air skrin penuh

Anda boleh menyemak kesan pada halaman maklumat peribadi di dalam dan di luar AlibabaKelebihan: Imej dihasilkan oleh bahagian belakang dan selamat;

Kelemahan: Anda perlu memulakan permintaan http untuk mendapatkan maklumat imej;

Paparan kesan: Memandangkan ia adalah sistem dalaman, ia tidak mudah untuk memaparkan kesan.

2. DOM melaksanakan tera air imej penuh dan tera air imej

Dapatkan lebar dan ketinggian imej dalam peristiwa pemuatan imej, jana kawasan tera air mengikut saiz imej, sekatnya pada lapisan atas imej, dan kandungan DOM ditanda air Copywriting atau maklumat lain agak mudah untuk dilaksanakan.

Kelebihan: mudah dan mudah dilaksanakan;

Kelemahan: terlalu besar atau terlalu banyak gambar akan menjejaskan prestasi

3, pelaksanaan kanvas (Penyelesaian pelaksanaan versi pertama )

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

const wrap = document.querySelector(&#39;#ReactApp&#39;);

const { clientWidth, clientHeight } = wrap;

const waterHeight = 120;

const waterWidth = 180;

// 计算个数

const [columns, rows] = [~~(clientWidth / waterWidth), ~~(clientHeight / waterHeight)]

for (let i = 0; i < columns; i++) {

    for (let j = 0; j <= rows; j++) {

        const waterDom = document.createElement(&#39;p&#39;);

        // 动态设置偏移值

        waterDom.setAttribute(&#39;style&#39;, `

            width: ${waterWidth}px;

            height: ${waterHeight}px;

            left: ${waterWidth + (i - 1) * waterWidth + 10}px;

            top: ${waterHeight + (j - 1) * waterHeight + 10}px;

            color: #000;

            position: absolute`

        );

        waterDom.innerText = &#39;测试水印&#39;;

        wrap.appendChild(waterDom);

    }

}

Salin selepas log masuk

Kaedah 1: Beroperasi terus pada imej

Tanpa berlengah lagi, masukkan kod

Kelebihan: Pelaksanaan bahagian hadapan tulen, klik kanan pada imej yang disalin Terdapat juga tera air;

Kaedah 2: kanvas menjana url tera air dan menetapkannya kepada atribut latar belakang css

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

useEffect(() => {

      // gif 图不支持

    if (src && src.includes(&#39;.gif&#39;)) {

      setShowImg(true);

    }

    image.onload = function () {

      try {

        // 太小的图不加载水印

        if (image.width < 10) {

          setIsDataError(true);

          props.setIsDataError && props.setIsDataError(true);

          return;

        }

        const canvas = canvasRef.current;

        canvas.width = image.width;

        canvas.height = image.height;

        // 设置水印

        const font = `${Math.min(Math.max(Math.floor(innerCanvas.width / 14), 14), 48)}px` || fontSize;

        innerContext.font = `${font} ${fontFamily}`;

        innerContext.textBaseline = &#39;hanging&#39;;

        innerContext.rotate(rotate * Math.PI / 180);

        innerContext.lineWidth = lineWidth;

        innerContext.strokeStyle = strokeStyle;

        innerContext.strokeText(text, 0, innerCanvas.height / 4 * 3);

        innerContext.fillStyle = fillStyle;

        innerContext.fillText(text, 0, innerCanvas.height / 4 * 3);

        const context = canvas.getContext(&#39;2d&#39;);

        context.drawImage(this, 0, 0);

        context.rect(0, 0, image.width || 200, image.height || 200);

           // 设置水印浮层

        const pattern = context.createPattern(innerCanvas, &#39;repeat&#39;);

        context.fillStyle = pattern;

        context.fill();

      } catch (err) {

        console.info(err);

        setShowImg(true);

      }

    };

    image.onerror = function () {

      setShowImg(true);

    };

  }, [src]);

Salin selepas log masuk
Kelebihan: Pelaksanaan bahagian hadapan tulen, menyokong domain silang, menyokong tera air imej git;

Kelemahan : Url base64 yang dihasilkan adalah agak besar; daripada imej dengan kanvas bukan gambar dalam kaedah pertama , supaya kelemahan kedua-dua penyelesaian dapat dielakkan dengan sempurna. Tetapi berhenti seketika dan fikirkan tentangnya. Adakah terdapat cara yang lebih mudah dan mudah untuk menggabungkan kedua-dua penyelesaian dan menggunakan kanvas untuk melukis? Ya, gunakan svg sebaliknya.

4, kaedah SVG (penyelesaian yang digunakan)

Memberi versi tindak balas komponen tera air.

Kelebihan: menyokong tera air gif, tiada isu merentas domain, menggunakan atribut berulang, tiada sisipan ke dalam proses dom, tiada masalah prestasi; >

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

export const getBase64Background = (props) => {

  const { nick, empId } = GlobalConfig.userInfo;

  const {

    rotate = -20,

    height = 75,

    width = 85,

    text = `${nick}-${empId}`,

    fontSize = &#39;14px&#39;,

    lineWidth = 2,

    fontFamily = &#39;microsoft yahei&#39;,

    strokeStyle = &#39;rgba(255, 255, 255, .15)&#39;,

    fillStyle = &#39;rgba(0, 0, 0, 0.15)&#39;,

    position = { x: 30, y: 30 },

  } = props;

  const image = new Image();

  image.crossOrigin = &#39;Anonymous&#39;;

  const canvas = document.createElement(&#39;canvas&#39;);

  const context = canvas.getContext(&#39;2d&#39;);

  canvas.width = width;

  canvas.height = height;

  context.font = `${fontSize} ${fontFamily}`;

  context.lineWidth = lineWidth;

  context.rotate(rotate * Math.PI / 180);

  context.strokeStyle = strokeStyle;

  context.fillStyle = fillStyle;

  context.textAlign = &#39;center&#39;;

  context.textBaseline = &#39;hanging&#39;;

  context.strokeText(text, position.x, position.y);

  context.fillText(text, position.x, position.y);

  return canvas.toDataURL(&#39;image/png&#39;);

};

 

// 使用方式

<img src="https://xxx.xxx.jpg" />

<p className="warter-mark-area" style={{ backgroundImage: `url(${getBase64Background({})})` }} />

Salin selepas log masuk

Soalan 1:

Jika dom tera air itu dipadam, bukankah imej itu tiada tera air?

Jawapan:

Anda boleh menggunakan MutationObserver untuk memantau nod air Jika nod diubah, imej akan disembunyikan; >Klik kanan tetikus Salin gambar?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

export const WaterMark = (props) => {

  // 获取水印数据

  const { nick, empId } = GlobalConfig.userInfo;

  const boxRef = React.createRef();

  const [waterMarkStyle, setWaterMarkStyle] = useState(&#39;180px 120px&#39;);

  const [isError, setIsError] = useState(false);

  const {

    src, text = `${nick}-${empId}`, height: propsHeight, showSrc, img, nick, empId

  } = props;

  // 设置背景图和背景图样式

  const boxStyle = {

    backgroundSize: waterMarkStyle,

    backgroundImage: `url("data:image/svg+xml;utf8,<svg width=\&#39;100%\&#39; height=\&#39;100%\&#39; xmlns=\&#39;http://www.w3.org/2000/svg\&#39; version=\&#39;1.1\&#39;><text width=\&#39;100%\&#39; height=\&#39;100%\&#39; x=\&#39;20\&#39; y=\&#39;68\&#39;  transform=\&#39;rotate(-20)\&#39; fill=\&#39;rgba(0, 0, 0, 0.2)\&#39; font-size=\&#39;14\&#39; stroke=\&#39;rgba(255, 255, 255, .2)\&#39; stroke-width=\&#39;1\&#39;>${text}</text></svg>")`,

  };

  const onLoad = (e) => {

    const dom = e.target;

    const {

      previousSibling, nextSibling, offsetLeft, offsetTop,

    } = dom;

    // 获取图片宽高

    const { width, height } = getComputedStyle(dom);

    if (parseInt(width.replace(&#39;px&#39;, &#39;&#39;)) < 180) {

      setWaterMarkStyle(`${width} ${height.replace(&#39;px&#39;, &#39;&#39;) / 2}px`);

    };

    previousSibling.style.height = height;

    previousSibling.style.width = width;

    previousSibling.style.top = `${offsetTop}px`;

    previousSibling.style.left = `${offsetLeft}px`;

    // 加载 loading 隐藏

    nextSibling.style.display = &#39;none&#39;;

  };

  const onError = (event) => {

    setIsError(true);

  };

  return (

    <p className={styles.water_mark_wrapper} ref={boxRef}>

      <p className={styles.water_mark_box} style={boxStyle} />

      {isError

        ? <ErrorSourceData src={src} showSrc={showSrc} height={propsHeight} text="图片加载错误" helpText="点击复制图片链接" />

        : (

          <>

            <img onLoad={onLoad} referrerPolicy="no-referrer" onError={onError} src={src} alt="图片显示错误" />

            <Icon className={styles.img_loading} type="loading" />

          </>

        )

      }

    </p>

  );

};

Salin selepas log masuk
Jawapan:

Semua gambar mempunyai fungsi klik kanan dilumpuhkan

Soalan 3: Bagaimana jika maklumat gambar diperoleh daripada rangkaian konsol?

Jawapan:

Pada masa ini tiada penyelesaian yang baik untuk operasi ini adalah disyorkan untuk menggunakan penyelesaian pelaksanaan bahagian belakang

Ringkasan

Penyelesaian tera air yang dilaksanakan di bahagian hadapan sentiasa hanya penyelesaian sementara, dan pelaksanaan bahagian belakang perniagaan menggunakan sumber pelayan Malah, penyelesaian yang paling ideal adalah menyediakan perkhidmatan tera air bebas Walaupun pemuatan Akan terdapat sedikit kelewatan dalam proses, tetapi berbanding dengan keselamatan data, kelewatan peringkat milisaat masih boleh diterima, yang memastikan kestabilan perkhidmatan perniagaan tidak terjejas.

Semasa proses Soal Jawab harian, banyak pihak perniagaan akan datang kepada saya untuk membincangkan titik risiko penyumbatan tanda air. Saya hanya boleh membalasnya dengan kepentingan keselamatan data setiap kali tera air, Ketelusan dan ketumpatan juga sedang dioptimumkan secara berterusan. Saya percaya akan ada versi yang bukan sahaja berfungsi sebagai tera air, tetapi juga menyelesaikan masalah oklusi dengan lebih baik.

Pembelajaran yang disyorkan: tutorial video html

Atas ialah kandungan terperinci Adakah anda tahu bagaimana bahagian hadapan melaksanakan penanda air?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:segmentfault.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan