vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue3 TypeScript文件URL转Base64

在Vue3+TypeScript中将文件URL转Base64的三种方法

作者:BillKu

这篇文章详细介绍了在Vue3项目中将blob URL转换为Base64格式的三种方法,包括使用FileReader、完整的Vue3组件示例以及使用axios的方案,重点说明了转换过程、性能考虑、错误处理以及后端接收等方面的关键点,需要的朋友可以参考下

在 Vue3 项目中,你已经有了 blob URL,需要将其转换为 Base64 格式。以下是完整的解决方案:

方法一:使用 FileReader

import { ref } from 'vue'

// 将单个 blob URL 转换为 Base64
const blobUrlToBase64 = async (blobUrl) => {
  try {
    // 1. 通过 fetch 获取 blob 数据
    const response = await fetch(blobUrl)
    const blob = await response.blob()
    
    // 2. 使用 FileReader 转换为 Base64
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => {
        // 移除 data URL 前缀,只保留纯 Base64 数据
        const base64 = reader.result.split(',')[1]
        resolve(base64)
      }
      reader.onerror = reject
      reader.readAsDataURL(blob)
    })
  } catch (error) {
    console.error('转换失败:', error)
    throw error
  }
}

// 批量转换多个 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'
]

// 转换并发送到后端
const handleUpload = async () => {
  try {
    const base64List = await convertAllToBase64(imageBase64Datas)
    
    // 发送到后端
    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 ? '转换中...' : '上传图片' }}
    </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('')

// 转换单个 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)
  })
}

// 转换所有图片并上传
const convertAndUpload = async () => {
  if (!props.imageBase64Datas.length) return
  
  loading.value = true
  error.value = ''
  
  try {
    // 批量转换所有 blob URL
    const conversionPromises = props.imageBase64Datas.map(blobToBase64)
    const base64Images = await Promise.all(conversionPromises)
    
    console.log('转换后的 Base64 数据:', base64Images)
    
    // 发送到后端
    await sendToBackend(base64Images)
    
  } catch (err) {
    error.value = `转换失败: ${err.message}`
    console.error('转换错误:', err)
  } finally {
    loading.value = false
  }
}

// 发送数据到后端
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('转换失败:', 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
  }
}

关键点说明

转换过程

性能考虑

错误处理

后端接收

选择适合你项目需求的方法即可。方法一提供了最基础的实现,方法二提供了完整的 Vue3 组件示例。

实例代码:

src\views\resources\emergency\comps\EmergencyInDialog.vue

// 确定
const onConfirmClick = async () => {
  // 预防性检查,导入期间,点击确定不执行任何操作
  if (tableLoading.value) {
    ElMessage.warning("正在导入,请等待!");
    return;
  }

  // 检查
  if (!check()) {
    return;
  }

  // 遍历选集,处理每个元素的imageBase64Datas,将每个 blob URL 转换为 Base64,回写到 imageBase64Datas
  for (const item of tableSelection.value) {
    if (item.imageBase64Datas && item.imageBase64Datas.length > 0) {
      try {
        // 转换 blob URL 为 Base64
        const base64Promises = item.imageBase64Datas.map(async (blobUrl) => {
          try {
            // 返回 blob 数据
            return await fileUrlToBase64(blobUrl);
          } catch (error) {
            console.error(`转换 blob URL 失败: ${blobUrl}`, error);
            // 返回 null,因为用的是map必须有返回,如果单个转换失败,不中断整个流程
            return null;
          }
        });

        // 等待所有图片转换完成
        const base64Results = await Promise.all(base64Promises);

        // 过滤掉转换失败的结果,并更新到原数据中
        item.imageBase64Datas = base64Results.filter(
          (result): result is string => result !== null && result !== undefined
        ) as string[];
      } catch (error) {
        console.error(`处理项目 ${item.id} 的图片数据失败:`, error);
        // 如果整个项目转换失败,清空图片数据,避免影响后续流程
        item.imageBase64Datas = [];
      }
    } else {
      // 如果没有图片数据,确保字段存在且为空数组
      item.imageBase64Datas = [];
    }
  }

  // 生成应急物资
  await store.fetchGenerateEmergency(tableSelection.value);
  // 删除确定的选集数据
  deleteConfirmData();
  // 关闭模态框
  closeDialog();
};

src\utils\fileUtils.ts

/**
 * 将文件url转换为blob
 * @param fileUrl
 * @returns blob
 */
export const fileUrlToBlob = async (fileUrl: string): Promise<Blob> => {
  const response = await fetch(fileUrl);
  return await response.blob();
};

/**
 * 将Blob转换为Base64
 * @param blob blob数据
 * @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)转换为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转换为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转Base64的三种方法的详细内容,更多关于Vue3 TypeScript文件URL转Base64的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文