vue 項目文件流數據格式轉blob圖片預覽展示


為了圖片安全性,有時候上傳圖片后后台不會直接返回圖片地址,會返回文件流的數據格式,這種格式需要處理下才能展示在頁面上
 
// 使用axios請求上傳接口
 axios({
    method: 'get',
    url: url, // 請求地址
    responseType: 'blob' // 設置接收格式為blob格式
  }).then(res => {
    // console.log(res)
    if (res && res.data && res.data.size) {
      const dataInfo = res.data
      let reader = new window.FileReader()
      // 使用readAsArrayBuffer讀取文件, result屬性中將包含一個 ArrayBuffer 對象以表示所讀取文件的數據
      reader.readAsArrayBuffer(dataInfo)
      reader.onload = function (e) {
        const result = e.target.result
        const contentType = dataInfo.type
        // 生成blob圖片,需要參數(字節數組, 文件類型)
        const blob = new Blob([result], { type: contentType })
        // 使用 Blob 創建一個指向類型化數組的URL, URL.createObjectURL是new Blob文件的方法,可以生成一個普通的url,可以直接使用,比如用在img.src上
        const url = window.URL.createObjectURL(blob)
        console.log(url) // 產生一個類似 blob:d3958f5c-0777-0845-9dcf-2cb28783acaf 這樣的URL字符串
      }
    }
  })
 
其他文件格式轉換:
base64圖片轉成blob圖片,一般base64圖片鏈接比較長,使用鏈接跳轉打開時不太友好,可能會解析錯誤,可以轉成blob圖片打開
// 獲取base64圖片, url圖片地址,
  // 如果返回的圖片地址不是base64格式,可以通過這個方法轉換成base64
  getFile (url) {
    let reader = new FileReader()
    reader.readAsDataURL(url)
    reader.onload = function (e) {
      const base64Data = e.target.result
      // 調用dataURItoBlob轉換方法
      console.log(this.dataURItoBlob (base64Data))
    }
  },

  // 將base64圖片轉化成blob圖片, base64Data base64圖片地址
  dataURItoBlob (base64Data) {
    // console.log(base64Data, base64Data.length)
    let byteString = base64Data
    if (base64Data.split(',')[0].indexOf('base64') >= 0) {
      byteString = atob(base64Data.split(',')[1]) // base64 解碼
    } else {
      byteString = unescape(base64Data.split(',')[1])
    }
    // 獲取文件類型
    let mimeString = base64Data.split(',')[0].match(/:(.*?);/)[1] // mime類型

    // ArrayBuffer 對象用來表示通用的、固定長度的原始二進制數據緩沖區
    // let arrayBuffer = new ArrayBuffer(byteString.length) // 創建緩沖數組
    // let uintArr = new Uint8Array(arrayBuffer) // 創建視圖

    let uintArr = new Uint8Array(byteString.length) // 創建視圖

    for (let i = 0; i < byteString.length; i++) {
      uintArr[i] = byteString.charCodeAt(i)
    }
    // 生成blob圖片
    const blob = new Blob([uintArr], {
      type: mimeString
    })
    console.log(uintArr, blob)
    // 使用 Blob 創建一個指向類型化數組的URL, URL.createObjectURL是new Blob文件的方法,可以生成一個普通的url,可以直接使用,比如用在img.src上
    return URL.createObjectURL(blob)
  }

 

最近做登錄的圖片驗證碼,發現把接收格式設置成arraybuffer,更簡單,這里把方法補充一下,一般我們的項目會有一個axios配置文件,設置請求攔截,響應,在這里我們要先設置一下

axios.js文件

import axios from 'axios'
import {
  Message
} from 'element-ui'
import store from '@/store'
import {
  getToken
} from '@/utils/auth'
import router from '@/router'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  // withCredentials: true, // 跨域發送cookies配置
  timeout: 10000,
  method: 'post'
})

service.interceptors.request.use(
  config => {
    if (store.getters.token) {
      config.headers['X-Token'] = getToken()
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.responseCode) { // 其他的都是一些常規配置,根據你自己項目配置就好,主要注意這里加個判斷,因為如果是文件流,是不會返回正常接口的res,code,data之類的數據,直接是一串字符,這里需要判斷一下是不是文件流數據
      if (res.responseCode !== '000000' && res.responseCode !== '000025') {
        Message({
          message: res.responseMsg || 'Error',
          type: 'error',
          duration: 2 * 1000
        })
        // 重新登錄
        if (res.responseCode === '000001') {
          setTimeout(function() {
            store.dispatch('user/resetToken').then(() => {
              router.replace('/login')
            })
          }, 3000)
        }
        return Promise.reject(new Error(res.message || 'Error'))
      } else {
        return res
      }
    } else { // 如果沒有返回responseCode,說明是文件流數據,直接把結果返回去
      return res }
  },
  error => {
    Message({
      message: error.message,
      type: 'error',
      duration: 2 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

如果你的接口請求沒有自己進行二次封裝,使用統一請求方法的的,這里不能使用統一方法,需要單獨引入axios,單獨設置返回數據格式,或者你在請求攔截那里判斷,如果是請求驗證碼接口就把返回格式設置成arrayBuffer,

import axios from './axios'

axios({
    url: '/kaptcha/getKaptcha',
    method: 'post',
    responseType: 'arraybuffer'
  }).then(res => {
        console.log(66, res)
        const blob = new Blob([res], { type: 'image/jpeg' })
        const u = window.URL.createObjectURL(blob)
        this.imgCode = u
      })

打印的結果

后台接口看到效果

 

實際效果

 

 

參考文檔: https://developer.mozilla.org/zh-CN/docs/Web/API/Blob

    https://blog.csdn.net/qq_34664239/article/details/94595508


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM