偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

探索前端黑科技——通過png圖的rgba值緩存數(shù)據(jù)

開發(fā) 前端
說起前端緩存,大部分人想到的無非是幾個(gè)常規(guī)的方案,比如cookie,localStorage,sessionStorage,或者加上indexedDB和webSQL,以及manifest離線緩存。除此之外,到底還有沒有別的方法可以進(jìn)行前端的數(shù)據(jù)緩存呢?這篇文章將會(huì)帶你一起來探索,如何一步一步地通過png圖的rgba值來緩存數(shù)據(jù)的黑科技之旅。

說起前端緩存,大部分人想到的無非是幾個(gè)常規(guī)的方案,比如cookie,localStorage,sessionStorage,或者加上indexedDB和webSQL,以及manifest離線緩存。除此之外,到底還有沒有別的方法可以進(jìn)行前端的數(shù)據(jù)緩存呢?這篇文章將會(huì)帶你一起來探索,如何一步一步地通過png圖的rgba值來緩存數(shù)據(jù)的黑科技之旅。

原理

我們知道,通過為靜態(tài)資源設(shè)置Cache-Control和Expires響應(yīng)頭,可以迫使瀏覽器對(duì)其進(jìn)行緩存。瀏覽器在向后臺(tái)發(fā)起請(qǐng)求的時(shí)候,會(huì)先在自身的緩存里面找,如果緩存里面沒有,才會(huì)繼續(xù)向服務(wù)器請(qǐng)求這個(gè)靜態(tài)資源。利用這一點(diǎn),我們可以把一些需要被緩存的信息通過這個(gè)靜態(tài)資源緩存機(jī)制來進(jìn)行儲(chǔ)存。

那么我們?nèi)绾伟研畔懭氲届o態(tài)資源中呢?canvas提供了.getImageData()方法和.createImageData()方法,可以分別用于讀取和設(shè)置圖片的rgba值。所以我們可以利用這兩個(gè)API進(jìn)行信息的讀寫操作。

接下來看原理圖:

 

當(dāng)靜態(tài)資源進(jìn)入緩存,以后的任何對(duì)于該圖片的請(qǐng)求都會(huì)先查找本地緩存,也就是說信息其實(shí)已經(jīng)以圖片的形式被緩存到本地了。

注意,由于rgba值只能是[0, 255]之間的整數(shù),所以本文所討論的方法僅適用于純數(shù)字組成的數(shù)據(jù)。

靜態(tài)服務(wù)器

我們使用node搭建一個(gè)簡(jiǎn)單的靜態(tài)服務(wù)器:

  1. const fs = require('fs'
  2.  
  3. const http = require('http'
  4.  
  5. const url = require('url'
  6.  
  7. const querystring = require('querystring'
  8.  
  9. const util = require('util'
  10.  
  11.   
  12.  
  13. const server = http.createServer((req, res) => { 
  14.  
  15.   let pathname = url.parse(req.url).pathname 
  16.  
  17.   let realPath = 'assets' + pathname 
  18.  
  19.   console.log(realPath) 
  20.  
  21.   if (realPath !== 'assets/upload') { 
  22.  
  23.      fs.readFile(realPath, "binary"function(err, file) { 
  24.  
  25.       if (err) { 
  26.  
  27.         res.writeHead(500, {'Content-Type''text/plain'}) 
  28.  
  29.         res.end(err) 
  30.  
  31.       } else { 
  32.  
  33.         res.writeHead(200, { 
  34.  
  35.           'Access-Control-Allow-Origin''*'
  36.  
  37.           'Content-Type''image/png'
  38.  
  39.           'ETag'"666666"
  40.  
  41.           'Cache-Control''public, max-age=31536000'
  42.  
  43.           'Expires''Mon, 07 Sep 2026 09:32:27 GMT' 
  44.  
  45.         }) 
  46.  
  47.         res.write(file, "binary"
  48.  
  49.         res.end() 
  50.  
  51.       } 
  52.  
  53.    }) 
  54.  
  55.   } else { 
  56.  
  57.     let post = '' 
  58.  
  59.     req.on('data', (chunk) => { 
  60.  
  61.       post += chunk 
  62.  
  63.     }) 
  64.  
  65.     req.on('end', () => { 
  66.  
  67.       post = querystring.parse(post) 
  68.  
  69.       console.log(post.imgData) 
  70.  
  71.       res.writeHead(200, { 
  72.  
  73.         'Access-Control-Allow-Origin''*' 
  74.  
  75.       }) 
  76.  
  77.       let base64Data = post.imgData.replace(/^data:image\/\w+;base64,/, ""
  78.  
  79.       let dataBuffer = new Buffer(base64Data, 'base64'
  80.  
  81.       fs.writeFile('assets/out.png', dataBuffer, (err) => { 
  82.  
  83.         if (err) { 
  84.  
  85.           res.write(err) 
  86.  
  87.           res.end() 
  88.  
  89.         } 
  90.  
  91.         res.write('OK'
  92.  
  93.         res.end() 
  94.  
  95.       }) 
  96.  
  97.     }) 
  98.  
  99.   } 
  100.  
  101. }) 
  102.  
  103.   
  104.  
  105. server.listen(80) 
  106.  
  107.   
  108.  
  109. console.log('Listening on port: 80' 

這個(gè)靜態(tài)資源的功能很簡(jiǎn)單,它提供了兩個(gè)功能:通過客戶端傳來的base64生成圖片并保存到服務(wù)器;設(shè)置圖片的緩存時(shí)間并發(fā)送到客戶端。

關(guān)鍵部分是設(shè)置響應(yīng)頭:

  1. res.writeHead(200, { 
  2.  
  3.   'Access-Control-Allow-Origin''*'
  4.  
  5.   'Content-Type''image/png'
  6.  
  7.   'ETag'"666666"
  8.  
  9.   'Cache-Control''public, max-age=31536000'
  10.  
  11.   'Expires''Mon, 07 Sep 2026 09:32:27 GMT' 
  12.  
  13. })  

我們?yōu)檫@張圖片設(shè)置了一年的Content-Type和十年的Expires,理論上足夠長(zhǎng)了。下面我們來進(jìn)行客戶端的coding。

客戶端

  1. <!-- client.html --> 
  2.  
  3.   
  4.  
  5. <canvas id="canvas" width="8", height="1"></canvas>  

假設(shè)我們需要存儲(chǔ)的是32位的數(shù)據(jù),所以我們?yōu)閏anvas設(shè)置寬度為8,高度為1。到底為什么32位數(shù)據(jù)對(duì)應(yīng)長(zhǎng)度為8,是因?yàn)槊恳粋€(gè)像素都有一個(gè)rgba,對(duì)應(yīng)著red,green,blue和alpha4個(gè)數(shù)值,所以需要除以4。

  1. <!-- client.js --> 
  2.  
  3.   
  4.  
  5. let keyString = '01234567890123456789012345678901' 
  6.  
  7.          
  8.  
  9. let canvas = document.querySelector('#canvas'
  10.  
  11. let ctx = canvas.getContext('2d'
  12.  
  13.   
  14.  
  15. let imgData = ctx.createImageData(8, 1) 
  16.  
  17.   
  18.  
  19. for (let i = 0; i < imgData.data.length; i += 4) { 
  20.  
  21.     imgData.data[i + 0] = parseInt(keyString[i]) + 50 
  22.  
  23.     imgData.data[i + 1] = parseInt(keyString[i + 1]) + 100 
  24.  
  25.     imgData.data[i + 2] = parseInt(keyString[i + 2]) + 150 
  26.  
  27.     imgData.data[i + 3] = parseInt(keyString[i + 3]) + 200 
  28.  
  29.  
  30.   
  31.  
  32. ctx.putImageData(imgData, 0, 0)  

首先我們假設(shè)需要被緩存的字符串為32位的01234567890123456789012345678901,然后我們使用.createImageData(8, 1)生成一個(gè)空白的imgData對(duì)象。接下來,我們對(duì)這個(gè)空對(duì)象進(jìn)行賦值。為了實(shí)驗(yàn)效果更加直觀,我們對(duì)rgba值都進(jìn)行了放大。設(shè)置完了imgData以后,通過.putImageData()方法把它放入我們的canvas即可。

我們現(xiàn)在可以打印一下,看看這個(gè)imgData是什么:

  1. // console.log(imgData.data) 
  2.  
  3. [50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201]  

接下來,我們要把這個(gè)canvas編譯為一張圖片的base64并發(fā)送給服務(wù)器,同時(shí)接收服務(wù)器的響應(yīng),對(duì)圖片進(jìn)行緩存:

  1. $.post('http://xx.xx.xx.xx:80/upload', { imgData: canvas.toDataURL() }, (data) => { 
  2.  
  3.     if (data === 'OK') { 
  4.  
  5.         let img = new Image() 
  6.  
  7.         img.crossOrigin = "anonymous" 
  8.  
  9.         img.src = 'http://xx.xx.xx.xx:80/out.png' 
  10.  
  11.         img.onload = () => { 
  12.  
  13.             console.log('完成圖片請(qǐng)求與緩存'
  14.  
  15.             ctx.drawImage(img, 0, 0) 
  16.  
  17.             console.log(ctx.getImageData(0, 0, 8, 1).data) 
  18.  
  19.         } 
  20.  
  21.     } 
  22.  
  23. })  

代碼很簡(jiǎn)單,通過.toDataURL()方法把base64發(fā)送到服務(wù)器,服務(wù)器處理后生成圖片并返回,其圖片資源地址為http://xx.xx.xx.xx:80/out.png。在img.onload后,其實(shí)圖片就已經(jīng)完成了本地緩存了,我們?cè)谶@個(gè)事件當(dāng)中把圖片信息打印出來,作為和源數(shù)據(jù)的對(duì)比。

結(jié)果分析

開啟服務(wù)器,運(yùn)行客戶端,***次加載的時(shí)候通過控制臺(tái)可以看到響應(yīng)的圖片信息:

 

200 OK,證明是從服務(wù)端獲取的圖片。

關(guān)閉當(dāng)前頁(yè)面,重新載入:

 

200 OK (from cache),證明是從本地緩存讀取的圖片。

接下來直接看rgba值的對(duì)比:

源數(shù)據(jù): [50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201]

緩存數(shù)據(jù):[50, 100, 152, 245, 54, 105, 157, 246, 57, 109, 149, 244, 52, 103, 154, 245, 56, 107, 157, 247, 50, 100, 152, 245, 54, 105, 157, 246, 57, 109, 149, 244]

之前得到的結(jié)論,源數(shù)據(jù)與緩存數(shù)據(jù)存在誤差的原因,經(jīng)查證后確定為alpha值的干擾所致。如果我們把a(bǔ)lpha值直接定為255,并且只把數(shù)據(jù)存放在rgb值內(nèi)部,即可消除誤差。下面是改良后的結(jié)果:

源數(shù)據(jù): [0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7, 8, 255, 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255]

緩存數(shù)據(jù):[0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7, 8, 255, 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255]

因?yàn)槲覒?,只是把a(bǔ)lpha值給定為255而沒有把循環(huán)賦值的邏輯進(jìn)行更新,所以第4n位的元數(shù)據(jù)被直接替換成了255,這個(gè)留著讀者自行修改有空再改……

綜上所述,這個(gè)利用png圖的rgba值緩存數(shù)據(jù)的黑科技,在理論上是可行的,但是在實(shí)際操作過程中可能還要考慮更多的影響因素,比如設(shè)法消除服務(wù)端的誤差,采取容錯(cuò)機(jī)制等。實(shí)際上也是可行的。

值得注意的是,localhost可能默認(rèn)會(huì)直接通過本地而不是服務(wù)器請(qǐng)求資源,所以在本地實(shí)驗(yàn)中,可以通過設(shè)置header進(jìn)行cors跨域,并且通過設(shè)置IP地址和80端口模擬服務(wù)器訪問。

后記

說是黑科技,其實(shí)原理非常簡(jiǎn)單,與之類似的還有通過Etag等方法進(jìn)行強(qiáng)緩存。研究的目的僅僅為了學(xué)習(xí),千萬不要作為非法之用。如果讀者們發(fā)現(xiàn)這篇文章有什么錯(cuò)漏之處,歡迎指正,也希望有興趣的朋友可以一起進(jìn)行討論。 

責(zé)任編輯:龐桂玉 來源: 前端大全
相關(guān)推薦

2016-09-13 21:59:09

Html5Http緩存

2024-03-18 08:33:16

2021-10-27 10:34:09

數(shù)據(jù)庫(kù)

2025-05-14 00:00:01

2015-10-21 13:38:28

2023-11-13 14:53:23

2023-04-07 08:43:47

Go語言應(yīng)用場(chǎng)

2017-07-07 10:24:56

云計(jì)算

2018-07-23 06:38:40

AI芯片數(shù)據(jù)中心

2025-03-24 01:00:00

2019-11-07 11:40:12

大數(shù)據(jù)Kafka技術(shù)

2016-01-29 17:53:20

Taste?Analy大數(shù)據(jù)云計(jì)算

2023-11-11 19:43:12

緩存數(shù)據(jù)庫(kù)

2016-07-14 16:40:56

黑科技

2023-09-22 08:27:39

2017-10-13 15:30:10

網(wǎng)頁(yè)黑科技性能

2015-01-22 10:17:05

微軟win10

2021-11-27 07:09:39

P 圖工具工具應(yīng)用軟件

2016-11-14 11:08:06

戴爾服務(wù)器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)