Rumah >hujung hadapan web >tutorial js >Adakah anda tahu bagaimana bahagian hadapan melaksanakan penanda air?
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.
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.
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
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'); });
Perlu memasang GraphicsMagick atau ImageMagick
2, nod-imej : https://github.com/zhangyuanwei/node-images
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('div'); // 动态设置偏移值 waterDom.setAttribute('style', ` 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 = '测试水印'; wrap.appendChild(waterDom); } }
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 )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('p'); // 动态设置偏移值 waterDom.setAttribute('style', ` 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 = '测试水印'; wrap.appendChild(waterDom); } }
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 cssuseEffect(() => { // gif 图不支持 if (src && src.includes('.gif')) { 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 = 'hanging'; 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('2d'); context.drawImage(this, 0, 0); context.rect(0, 0, image.width || 200, image.height || 200); // 设置水印浮层 const pattern = context.createPattern(innerCanvas, 'repeat'); context.fillStyle = pattern; context.fill(); } catch (err) { console.info(err); setShowImg(true); } }; image.onerror = function () { setShowImg(true); }; }, [src]);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; >export const getBase64Background = (props) => { const { nick, empId } = GlobalConfig.userInfo; const { rotate = -20, height = 75, width = 85, text = `${nick}-${empId}`, fontSize = '14px', lineWidth = 2, fontFamily = 'microsoft yahei', strokeStyle = 'rgba(255, 255, 255, .15)', fillStyle = 'rgba(0, 0, 0, 0.15)', position = { x: 30, y: 30 }, } = props; const image = new Image(); image.crossOrigin = 'Anonymous'; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); 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 = 'center'; context.textBaseline = 'hanging'; context.strokeText(text, position.x, position.y); context.fillText(text, position.x, position.y); return canvas.toDataURL('image/png'); }; // 使用方式 <img src="https://xxx.xxx.jpg" /> <p className="warter-mark-area" style={{ backgroundImage: `url(${getBase64Background({})})` }} />
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?
export const WaterMark = (props) => { // 获取水印数据 const { nick, empId } = GlobalConfig.userInfo; const boxRef = React.createRef(); const [waterMarkStyle, setWaterMarkStyle] = useState('180px 120px'); 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=\'100%\' height=\'100%\' xmlns=\'http://www.w3.org/2000/svg\' version=\'1.1\'><text width=\'100%\' height=\'100%\' x=\'20\' y=\'68\' transform=\'rotate(-20)\' fill=\'rgba(0, 0, 0, 0.2)\' font-size=\'14\' stroke=\'rgba(255, 255, 255, .2)\' stroke-width=\'1\'>${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('px', '')) < 180) { setWaterMarkStyle(`${width} ${height.replace('px', '') / 2}px`); }; previousSibling.style.height = height; previousSibling.style.width = width; previousSibling.style.top = `${offsetTop}px`; previousSibling.style.left = `${offsetLeft}px`; // 加载 loading 隐藏 nextSibling.style.display = 'none'; }; 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> ); };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
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!