JavaScript實(shí)現(xiàn)將圖片地址轉(zhuǎn)成文件流并上傳
寫(xiě)在開(kāi)頭
最近,小編在業(yè)務(wù)中遇到一個(gè)圖片轉(zhuǎn)存的場(chǎng)景。
領(lǐng)導(dǎo):大概過(guò)程就是,接口會(huì)給我返回一個(gè)圖片列表數(shù)據(jù),圖片路徑是全路徑,但是路徑中的域名是其他系統(tǒng)的,必須要在用戶選擇圖片的時(shí)候?qū)D片重新轉(zhuǎn)存到自個(gè)的系統(tǒng)上,防止其他系統(tǒng)刪除圖片對(duì)此有影響。
我:Em...很合理的需求。
(但是,和有什么關(guān)系?我只是一個(gè)前端小菜雞呀,不祥的預(yù)感.......)
我:(卑微提問(wèn))這個(gè)過(guò)程不是放后端做比較合理一點(diǎn)?
后端大哥:前端不能做?
我:可以可以,只是...這個(gè)好像會(huì)跨域?
后端大哥:已經(jīng)配置了請(qǐng)求頭('Access-Control-Allow-Origin': '*')。
我:哦,好的,我去弄一下。(*******此處省略幾萬(wàn)字心理活動(dòng)內(nèi)容)
第一種(推薦)
那么,迫于......不,我自愿的,我們來(lái)看看前端要如何完成這個(gè)轉(zhuǎn)成過(guò)程,代碼比較簡(jiǎn)單,直接貼上來(lái)瞧瞧:
async function imageToStorage(path) {
// 獲取文件名
const startIndex = path.lastIndexOf('/');
const endIndex = path.indexOf('?');
const imgName = path.substring(startIndex + 1, endIndex);
// 獲取圖片的文件流對(duì)象
const file = await getImgToFile(path, imgName);
// TODO: 將File對(duì)象上傳到其他接口中
}
/**
* @name 通過(guò)fetch請(qǐng)求文件,將文件轉(zhuǎn)成文件流對(duì)象
* @param { string } path 文件路徑全路徑
* @param { string } fileName 文件名
* @returns { File | undefined }
*/
function getImgToFile(path, fileName) {
const response = await fetch(path);
if (response) {
const blob = await response.blob();
const file = new File([blob], fileName, { type: blob.type });
return file;
}
}
上述方式,在后端配置了允許跨域后,正常是沒(méi)有什么問(wèn)題的,也是比較好的一種方式了。
但是,在小編實(shí)際第一次編碼測(cè)試后,卻還是遇上了跨域。

一猜應(yīng)該就是后端實(shí)際還沒(méi)配置好,問(wèn)了一下。
后端大哥:還沒(méi)部署,一會(huì)再自己試試。
我:嗯嗯。
第二種
等待的過(guò)程,小編又在網(wǎng)上找了找了,找到了第二種方式,各位看官可以瞧瞧:
/** @name 將圖片的網(wǎng)絡(luò)鏈接轉(zhuǎn)成base64 **/
function imageUrlToBase64(imageUrl: string, fileName: string): Promise<File> {
return new Promise(resolve => {
const image = new Image();
// 讓Image元素啟用cors來(lái)處理跨源請(qǐng)求
image.setAttribute('crossOrigin', 'anonymous');
image.src = imageUrl + '&v=' + Math.random();
image.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
const context = canvas.getContext('2d')!;
context.drawImage(image, 0, 0, image.width, image.height);
// canvas.toDataURL
const imageBase64 = canvas.toDataURL('image/jpeg', 1); // 第二個(gè)參數(shù)是壓縮質(zhì)量
// 將圖片的base64轉(zhuǎn)成文件流
const file = base64ToFile(imageBase64, fileName);
resolve(file);
};
});
}
/** @name 將圖片的base64轉(zhuǎn)成文件流 **/
function base64ToFile(base64: string, fileName: string) {
const baseArray = base64.split(',');
// 獲取類型與后綴名
const mime = baseArray[0].match(/:(.*?);/)![1];
const suffix = mime.split('/')[1];
// 轉(zhuǎn)換數(shù)據(jù)
const bstr = atob(baseArray[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
// 生成文件流
const file = new File([u8arr], `${fileName}.${suffix}`, {
type: mime,
});
return file;
}
這第二種方式由于要先把圖片繪制到 canvas 再去轉(zhuǎn)成 base64 再去轉(zhuǎn)成文件流,小編用 console.time 稍微測(cè)了一下,每次轉(zhuǎn)化過(guò)程都要幾百毫秒,圖片越大時(shí)間越長(zhǎng),挺影響性能的。
所以,小編還是推薦使用第一種方式,當(dāng)然,最穩(wěn)妥的方案是后端去搞最好了。
網(wǎng)上很多都說(shuō)第二種方式可以直接繞過(guò)跨域,各種談?wù)摗?/p>
主要就是這個(gè) crossOrigin 屬性。MDN解釋
它原理是通過(guò)了 CORS

或者可以再看看這個(gè)解釋:傳送門(mén)
到此這篇關(guān)于JavaScript實(shí)現(xiàn)將圖片地址轉(zhuǎn)成文件流并上傳的文章就介紹到這了,更多相關(guān)JavaScript圖片地址轉(zhuǎn)文件流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Axios實(shí)現(xiàn)無(wú)感知雙Token刷新的詳細(xì)教程
在現(xiàn)代系統(tǒng)中,Token認(rèn)證已成為保障用戶安全的標(biāo)準(zhǔn)做法,然而,盡管許多系統(tǒng)采用了這種認(rèn)證方式,卻在處理Token刷新方面存在不足,導(dǎo)致用戶體驗(yàn)不佳,許多系統(tǒng)未能提供一種無(wú)縫的、用戶無(wú)感知的Token刷新機(jī)制,所以本文介紹了教你用Axios實(shí)現(xiàn)無(wú)感知雙Token刷新2024-08-08
js實(shí)現(xiàn)點(diǎn)擊圖片將圖片地址復(fù)制到粘貼板的方法
這篇文章主要介紹了js實(shí)現(xiàn)點(diǎn)擊圖片將圖片地址復(fù)制到粘貼板的方法,涉及js操作節(jié)點(diǎn)的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-02-02
手動(dòng)實(shí)現(xiàn)js短信驗(yàn)證碼輸入框
本文記錄一下自己手動(dòng)實(shí)現(xiàn)的一個(gè)前端常見(jiàn)的短信驗(yàn)證碼輸入組件,從需求到實(shí)現(xiàn)逐步優(yōu)化的過(guò)程。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
JS實(shí)現(xiàn)隨機(jī)生成10個(gè)手機(jī)號(hào)的方法示例
這篇文章主要介紹了JS實(shí)現(xiàn)隨機(jī)生成10個(gè)手機(jī)號(hào)的方法,涉及javascript數(shù)值運(yùn)算與隨機(jī)數(shù)操作相關(guān)使用技巧,需要的朋友可以參考下2018-12-12
javascript下漢字和Unicode編碼互轉(zhuǎn)代碼
這個(gè)是就是把漢字和Unicode編碼互轉(zhuǎn)的javascript代碼,也是從網(wǎng)上找到了,也許有人用得著!!2010-10-10
針對(duì)BootStrap中tabs控件的美化和完善(推薦)
這篇文章主要介紹了針對(duì)BootStrap中tabs控件的美化和完善的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-07-07

