在Vue3+TypeScript中將文件URL轉(zhuǎn)Base64的三種方法
在 Vue3 項目中,你已經(jīng)有了 blob URL,需要將其轉(zhuǎn)換為 Base64 格式。以下是完整的解決方案:
方法一:使用 FileReader
import { ref } from 'vue'
// 將單個 blob URL 轉(zhuǎn)換為 Base64
const blobUrlToBase64 = async (blobUrl) => {
try {
// 1. 通過 fetch 獲取 blob 數(shù)據(jù)
const response = await fetch(blobUrl)
const blob = await response.blob()
// 2. 使用 FileReader 轉(zhuǎn)換為 Base64
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
// 移除 data URL 前綴,只保留純 Base64 數(shù)據(jù)
const base64 = reader.result.split(',')[1]
resolve(base64)
}
reader.onerror = reject
reader.readAsDataURL(blob)
})
} catch (error) {
console.error('轉(zhuǎn)換失敗:', error)
throw error
}
}
// 批量轉(zhuǎn)換多個 blob URL
const convertAllToBase64 = async (blobUrlList) => {
const base64Promises = blobUrlList.map(url => blobUrlToBase64(url))
return await Promise.all(base64Promises)
}
// 在組件中使用
const imageBase64Datas = [
'blob:http://localhost:5173/3125cc04-797d-4736-8e25-cbcee07a05ba',
'blob:http://localhost:5173/0409476c-a2d0-4021-b614-825fadac4e96'
]
// 轉(zhuǎn)換并發(fā)送到后端
const handleUpload = async () => {
try {
const base64List = await convertAllToBase64(imageBase64Datas)
// 發(fā)送到后端
const response = await fetch('/api/upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
images: base64List
})
})
if (response.ok) {
console.log('上傳成功')
}
} catch (error) {
console.error('上傳失敗:', error)
}
}方法二:完整的 Vue3 組件示例
<template>
<div>
<button @click="convertAndUpload" :disabled="loading">
{{ loading ? '轉(zhuǎn)換中...' : '上傳圖片' }}
</button>
<div v-if="error" class="error">{{ error }}</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
imageBase64Datas: {
type: Array,
required: true
}
})
const loading = ref(false)
const error = ref('')
// 轉(zhuǎn)換單個 blob URL 為 Base64
const blobToBase64 = (blobUrl) => {
return new Promise((resolve, reject) => {
fetch(blobUrl)
.then(response => response.blob())
.then(blob => {
const reader = new FileReader()
reader.onloadend = () => {
const base64 = reader.result.split(',')[1]
resolve({
base64,
mimeType: blob.type,
size: blob.size,
filename: `image_${Date.now()}.${blob.type.split('/')[1]}`
})
}
reader.onerror = reject
reader.readAsDataURL(blob)
})
.catch(reject)
})
}
// 轉(zhuǎn)換所有圖片并上傳
const convertAndUpload = async () => {
if (!props.imageBase64Datas.length) return
loading.value = true
error.value = ''
try {
// 批量轉(zhuǎn)換所有 blob URL
const conversionPromises = props.imageBase64Datas.map(blobToBase64)
const base64Images = await Promise.all(conversionPromises)
console.log('轉(zhuǎn)換后的 Base64 數(shù)據(jù):', base64Images)
// 發(fā)送到后端
await sendToBackend(base64Images)
} catch (err) {
error.value = `轉(zhuǎn)換失敗: ${err.message}`
console.error('轉(zhuǎn)換錯誤:', err)
} finally {
loading.value = false
}
}
// 發(fā)送數(shù)據(jù)到后端
const sendToBackend = async (images) => {
try {
const response = await fetch('/api/upload/images', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
images: images,
uploadTime: new Date().toISOString()
})
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const result = await response.json()
console.log('上傳成功:', result)
} catch (err) {
throw new Error(`上傳失敗: ${err.message}`)
}
}
</script>方法三:使用 axios(如果項目中使用 axios)
import axios from 'axios'
// 使用 axios 的版本
const blobToBase64WithAxios = async (blobUrl) => {
try {
const response = await axios.get(blobUrl, {
responseType: 'blob'
})
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
const base64 = reader.result.split(',')[1]
resolve(base64)
}
reader.onerror = reject
reader.readAsDataURL(response.data)
})
} catch (error) {
console.error('轉(zhuǎn)換失敗:', error)
throw error
}
}
// 上傳到后端
const uploadBase64Images = async (base64List) => {
try {
const response = await axios.post('/api/upload', {
images: base64List
}, {
headers: {
'Content-Type': 'application/json'
}
})
return response.data
} catch (error) {
console.error('上傳失敗:', error)
throw error
}
}關(guān)鍵點說明
轉(zhuǎn)換過程:
- 使用
fetch獲取 blob URL 對應(yīng)的實際數(shù)據(jù) - 通過
FileReader將 blob 轉(zhuǎn)換為 data URL - 從 data URL 中提取純 Base64 部分
性能考慮:
- 大文件轉(zhuǎn)換可能會影響性能
- 可以考慮分片上傳或壓縮圖片
錯誤處理:
- 添加適當(dāng)?shù)腻e誤處理
- 提供用戶反饋
后端接收:
- 確保后端能夠接收 Base64 字符串
- 可能需要同時發(fā)送文件類型信息
選擇適合你項目需求的方法即可。方法一提供了最基礎(chǔ)的實現(xiàn),方法二提供了完整的 Vue3 組件示例。
實例代碼:
src\views\resources\emergency\comps\EmergencyInDialog.vue
// 確定
const onConfirmClick = async () => {
// 預(yù)防性檢查,導(dǎo)入期間,點擊確定不執(zhí)行任何操作
if (tableLoading.value) {
ElMessage.warning("正在導(dǎo)入,請等待!");
return;
}
// 檢查
if (!check()) {
return;
}
// 遍歷選集,處理每個元素的imageBase64Datas,將每個 blob URL 轉(zhuǎn)換為 Base64,回寫到 imageBase64Datas
for (const item of tableSelection.value) {
if (item.imageBase64Datas && item.imageBase64Datas.length > 0) {
try {
// 轉(zhuǎn)換 blob URL 為 Base64
const base64Promises = item.imageBase64Datas.map(async (blobUrl) => {
try {
// 返回 blob 數(shù)據(jù)
return await fileUrlToBase64(blobUrl);
} catch (error) {
console.error(`轉(zhuǎn)換 blob URL 失敗: ${blobUrl}`, error);
// 返回 null,因為用的是map必須有返回,如果單個轉(zhuǎn)換失敗,不中斷整個流程
return null;
}
});
// 等待所有圖片轉(zhuǎn)換完成
const base64Results = await Promise.all(base64Promises);
// 過濾掉轉(zhuǎn)換失敗的結(jié)果,并更新到原數(shù)據(jù)中
item.imageBase64Datas = base64Results.filter(
(result): result is string => result !== null && result !== undefined
) as string[];
} catch (error) {
console.error(`處理項目 ${item.id} 的圖片數(shù)據(jù)失敗:`, error);
// 如果整個項目轉(zhuǎn)換失敗,清空圖片數(shù)據(jù),避免影響后續(xù)流程
item.imageBase64Datas = [];
}
} else {
// 如果沒有圖片數(shù)據(jù),確保字段存在且為空數(shù)組
item.imageBase64Datas = [];
}
}
// 生成應(yīng)急物資
await store.fetchGenerateEmergency(tableSelection.value);
// 刪除確定的選集數(shù)據(jù)
deleteConfirmData();
// 關(guān)閉模態(tài)框
closeDialog();
};src\utils\fileUtils.ts
/**
* 將文件url轉(zhuǎn)換為blob
* @param fileUrl
* @returns blob
*/
export const fileUrlToBlob = async (fileUrl: string): Promise<Blob> => {
const response = await fetch(fileUrl);
return await response.blob();
};
/**
* 將Blob轉(zhuǎn)換為Base64
* @param blob blob數(shù)據(jù)
* @returns Base64編碼字符串
*/
export const blobToBase64 = (blob: Blob): Promise<string> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
};
/**
* 將文件(類型為FiLe或Blob)轉(zhuǎn)換為Base64
* @param file 文件
* @returns Base64編碼字符串
*/
export const fileToBase64 = (file: File | Blob): Promise<string> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
};
/**
* 將文件url轉(zhuǎn)換為Base64
* @param fileUrl
* @returns
*/
export const fileUrlToBase64 = async (fileUrl: string): Promise<string | null> => {
const file = await fileUrlToBlob(fileUrl);
return await fileToBase64(file);
};以上就是在Vue3+TypeScript中將文件URL轉(zhuǎn)Base64的三種方法的詳細(xì)內(nèi)容,更多關(guān)于Vue3 TypeScript文件URL轉(zhuǎn)Base64的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue中以HTML形式顯示內(nèi)容并動態(tài)生成HTML代碼的方法
有的時候我們想在vue中直接顯示一個html的網(wǎng)頁,如果用富文本方式,那么內(nèi)容就會太多,那么怎么處理呢?這篇文章主要給大家介紹了關(guān)于Vue中如何以HTML形式顯示內(nèi)容并動態(tài)生成HTML代碼的相關(guān)資料,需要的朋友可以參考下2024-03-03
element-ui中的clickoutside點擊空白隱藏元素
這篇文章主要為大家介紹了element-ui中的clickoutside點擊空白隱藏元素示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03
Vue實例初始化為渲染函數(shù)設(shè)置檢查源碼剖析
這篇文章主要為大家介紹了Vue實例初始化為渲染函數(shù)設(shè)置檢查源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08
關(guān)于Vue父子組件傳參和回調(diào)函數(shù)的使用
這篇文章主要介紹了關(guān)于Vue父子組件傳參和回調(diào)函數(shù)的使用,我們將某段代碼封裝成一個組件,而這個組件又在另一個組件中引入,而引入該封裝的組件的文件叫做父組件,被引入的組件叫做子組件,需要的朋友可以參考下2023-05-05
vue使用require.context實現(xiàn)動態(tài)注冊路由
這篇文章主要介紹了vue使用require.context實現(xiàn)動態(tài)注冊路由的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12
vue項目動態(tài)路由刷新界面白屏undefined問題及解決
這篇文章主要介紹了vue項目動態(tài)路由刷新界面白屏undefined問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-07-07

