也是在最近一點(diǎn)時(shí)間寫小demo 遇到的一些問題
比如在用戶界面,用戶選擇本地的一張照片,前端把照片傳到后端,后端怎么把照片保存到服務(wù)器,然后返回給 圖片線上地址。也是找了一些文章,然后分享下。?
技術(shù)
前端:react
后端:egg.js(node框架)
base64 轉(zhuǎn)換?
轉(zhuǎn)二進(jìn)制 保存圖片
base64(mdn)
Base64?是一組相似的二進(jìn)制到文本(binary-to-text)的編碼規(guī)則,使得二進(jìn)制數(shù)據(jù)在解釋成 radix-64 的表現(xiàn)形式后能夠用 ASCII 字符串的格式表示出來。Base64?這個詞出自一種?MIME 數(shù)據(jù)傳輸編碼。
Base64 編碼普遍應(yīng)用于需要通過被設(shè)計(jì)為處理文本數(shù)據(jù)的媒介上儲存和傳輸二進(jìn)制數(shù)據(jù)而需要編碼該二進(jìn)制數(shù)據(jù)的場景。這樣是為了保證數(shù)據(jù)的完整并且不用在傳輸過程中修改這些數(shù)據(jù)。Base64 也被一些應(yīng)用(包括使用?MIME?的電子郵件)和在?XML?中儲存復(fù)雜數(shù)據(jù)時(shí)使用。
為什么轉(zhuǎn)成base64&好處
- 傳輸信道只支持ASCII字符,不方便傳輸二進(jìn)制流的場合。含有非ASCII字符,容易出現(xiàn)編碼問題。所以需要用base64轉(zhuǎn)化為ascii字符。Base64用于將二進(jìn)制數(shù)據(jù)編碼成ASCII字符 (圖片、文件等都可轉(zhuǎn)化為二進(jìn)制數(shù)據(jù))。
- 圖片的 base64 編碼就是可以將一副圖片數(shù)據(jù)編碼成一串字符串,使用該字符串代替圖像地址。
- 將圖片轉(zhuǎn)換為base64編碼最常見的應(yīng)用就是在將網(wǎng)頁中的一些圖片轉(zhuǎn)為base64編碼可以實(shí)現(xiàn)網(wǎng)頁圖片在網(wǎng)速 不好的時(shí)候先于內(nèi)容加載和減少http的請求次數(shù)來減少網(wǎng)站服務(wù)器的負(fù)擔(dān)。
獲取文件的base64格式
<!-- 我這里寫個簡單的樣式 -->
<input type="file">
<button>提交</button>
?選擇一張圖片文件,然后點(diǎn)擊提交按鈕我們就會得到一個 base64字符串
const files = document.querySelector('input[type=file]')
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
var reader = new FileReader();
reader.readAsDataURL(files.files[0]);
reader.onloadend = function () {
var base64 = reader.result;
console.log(base64);
}
})
console:
?我們可以通過這個 base64 格式的字符串,直接復(fù)制到瀏覽器的地址上,就能訪問圖片
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAADMUExURUdwTPn5+/j4/Pn5+/n5/Pn5+/n5+/n5+/j4+/n5+vv7+/j4+/n5+vv7+/n5+/j4+/j4+vn5+vn5/Pj4+/r6+vr6/Pn5+/n5+/r6+vr6/Pn5+/j4+vj4+gAAAPHx8wcHB0ZGRkdHSLS0trOztbKytLGxs2NjZAYGBkxMTfPz9dHR0pCQkggICPb2+F5eX2JiYxoaGkZGR4+PkdLS093d38jIyQkJCUtLTDc3N7W1t9PT1I2Nj2LkZLoAAAAkdFJOUwD+IpKwVQT57P1y0kIM58w8BvB03wjRW7kzYoka7wJtZbFuA8zxGUAAAAIESURBVFjDrZjpdoIwEIWjoIC7goJQ1w7a1ta6dt/7/u/UKNrWhWSCc/8y5ztAMncWxuLVbvqB3nBMwzCdhh74zTZLoLOO3oI9tfTOmRql7noWHJXluXU0pmiXQKCSXURhsjkTJDJzWTmnkgeE8hUJpqqlAKWUVhVx0mVAq5yO5xRqoKBaIY6TMUBJRuY4p2uBoqzu0fdR5nDSkXcqGJBAxsF/StcgkWp7Z1ctQ0KVd++TBoml7eRFKjko9S9bsnk4Qfm/DM7BScr9+o95Gsjc+pMNJ8re+KrID19eB3JQKXJfNz5ieReGD59ykrsGefEB85BrOJKCvHXdESTrJMSRrFWV6gsCxiGS1OGgnuD582JDupKAdF6XW6KA0RBHarVZUxxxjSQ1mQ8kJJ8FQEIKmA4kJJ015Pf25lZOajAH8KTFLDbEYSgL2ZLu462EoarQ4CMCvcfXJRRocBlxwm8ByFTgXEwFn+YocAQe58iPH8Xhx6+TcPiFDEg4PEV8Eg5PWqGNTLEcbiNCY5tjOdzYhFY7QXJWVoswfzlnbf6icjR745xHOWddjkQFEr7Gk6elPIk8WcnGypU3EShtmgiytoau0SJr/eiaUbL2mK5hpxshyIYaujGLbvCjG0XphmO6cZ1ugUC30qBbshCufegWUYSrsWhZ1+8dLut6qsu6SOcq68Mf88U7H+osen4AAAAASUVORK5CYII=
這串字符串其實(shí)就是一張照片的DataURL,就是利用base64編碼把圖片數(shù)據(jù)翻譯成標(biāo)準(zhǔn)ASCII字符。也可以把這個字符串直接放到?img 標(biāo)簽?src 上。這樣也可以節(jié)省 http網(wǎng)絡(luò)的一次請求
字符串的結(jié)構(gòu):
data:image/png;base64??????????聲明數(shù)據(jù)協(xié)議及類型名稱
base64? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??編碼形式為base64
iVBORw0KGgoAAAA...? ? ? ? ? ?內(nèi)容
?
?接下來我們開始完整的演示文件上傳的過程
前端: react(就是轉(zhuǎn)base64,上面已經(jīng)講到)
后端:egg.js(node)
前端
?
?
?
?
?很簡單的樣式,我這里做了一個回顯的效果就是獲取完 圖片的 base64 字符串然后 在賦值給img
//react
const fileRef = useRef(0)
const [ src, setSrc] = useState()
<img src={src} alt=""/>
<input type="file" name="" id="" ref={fileRef} onChange={(e) => fileBtn(e)}/>
函數(shù)? filebtn
function fileBtn(e){
var imgfile = e.target.files[0] //獲取文件信息
var reader = new FileReader();
reader.onload=function(){
var fileurl = reader.result
setSrc(fileurl) // 這個 useState 把獲取的base64 給到img 的src 上
// 這里有一個向后端發(fā)送的請求
postimg({
files: fileurl
}).then(res=>{
console.log(res);
})
}
reader.readAsDataURL(imgfile)
}
postimg 這里是封裝的一個請求 http 是一個 axios(網(wǎng)上封裝好的)(請求需要用 post)
function postimg(params){
return new Promise((resolve,reject)=>{
http('post','postimg',params).then(res=>{
resolve(res)
},error =>{
console.log("網(wǎng)絡(luò)異常~", error);
reject(error)
})
})
}
?到這里前端部分就已經(jīng)實(shí)現(xiàn)完畢了
后端
?首先在router 文件里編寫路由
router.post('/postimg', controller.home.postimg);
然后在controller 文件下 home 文件 里面的 postimg(這里強(qiáng)調(diào)下要用post 請求)
我們這里是用了一個中間件(方便我們獲取 參數(shù),不需要考慮 get 或者是 post)文章來源:http://www.zghlxwxcb.cn/news/detail-432221.html
params(key) {
const method = this.request.method;
if (method === 'GET') {
return key ? this.query[key] : this.query;
}
return key ? this.request.body[key] : this.request.body;
},
async postimg() {
const { ctx } = this;
const file = ctx.params().files; // 獲取參數(shù)
const imgtype = file.match(/data:image\/(png|jpep|jpg|JPG|gif|webp);/)[1];//獲取文件的類型
const filename = `${Math.floor(Math.random() * 10000000000)}.${imgtype}`;//獲取隨機(jī)數(shù)
const publi = `//${ctx.request.header.host}/public/updataImg/${filename}`; //返回的 文件路徑
const filepath = path.join(`${__dirname}/../public`, `updataImg/${filename}`);//寫入文件的路徑
const fileBuffer = Buffer.from(file.replace(/^data:image\/(png|jpep|jpg|gif|webp);base64,/, ''), 'base64'); //講base64 的 data:image/png;base64 去掉,并轉(zhuǎn)成而二進(jìn)制
console.log(publi, 123);
fs.writeFileSync(filepath, fileBuffer); //寫入文件
}
我這是用 egg 來寫的,如果用express或者koa 搭建的服務(wù)器,原理也是一樣,復(fù)制粘貼即可。文章來源地址http://www.zghlxwxcb.cn/news/detail-432221.html
到了這里,關(guān)于圖片上傳流程&前端上傳文件&后端保存文件&并返回圖片地址的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!