zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    1442. Count Triplets That Can Form Two Arrays of Equal XOR
    1441. Build an Array With Stack Operations
    312. Burst Balloons
    367. Valid Perfect Square
    307. Range Sum Query
    1232. Check If It Is a Straight Line
    993. Cousins in Binary Tree
    1436. Destination City
    476. Number Complement
    383. Ransom Note
  • 原文地址:https://www.cnblogs.com/steamed-twisted-roll/p/11821148.html
Copyright © 2011-2022 走看看