LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

线上项目https看不了http图片的解决办法

zhenglin
2025年12月2日 11:12 本文热度 314
解决方式:由后端转发,前端将图片url接口传给后端, 后端返回blob数据流展示,前端对图片url相同的进行缓存,不会重复发请求。

//封装方法utils/transitionImage.ts

import { previewImage } from '@/api/common'

 

// 跟踪正在加载的URL

export const loadingUrls = new Set<string>()

// 跟踪pending状态的请求(用于取消请求)

const pendingRequests = new Map<string, AbortController()

// 记录每个URL的最新请求序列号(确保响应顺序正确)

const requestSequence = new Map<string, number>()

 

export const getImageUrl = async (

  url: string,

  pictureUrlsRef: { value: Record<string, string> },

  forceUpdate = false

): Promise<string | undefined> => {

  if (!url) return

 

  // 生成当前请求的序列号

  const currentSeq = (requestSequence.get(url) || 0) + 1

  requestSequence.set(url, currentSeq)

 

  // 强制刷新时:取消旧请求(如果存在)

  if (forceUpdate) {

    // 清除旧缓存

    if (pictureUrlsRef.value[url]) {

      URL.revokeObjectURL(pictureUrlsRef.value[url])

      delete pictureUrlsRef.value[url]

    }

 

    // 取消pending的旧请求

    const existingController = pendingRequests.get(url)

    if (existingController) {

      existingController.abort() // 中断旧请求

      pendingRequests.delete(url)

      loadingUrls.delete(url) // 移除加载中标记

    }

  } else {

    // 非强制刷新:如果已有缓存,直接返回(核心逻辑)

    if (pictureUrlsRef.value[url]) {

      return pictureUrlsRef.value[url]

    }

    // 非强制刷新:如果正在加载,直接返回(避免重复请求)

    if (loadingUrls.has(url)) {

      return

    }

  }

 

  // 发起新请求(仅当无缓存、非加载中、或强制刷新时)

  const controller = new AbortController()

  pendingRequests.set(url, controller)

  loadingUrls.add(url)

 

  try {

    const res = await previewImage(encodeURIComponent(url), {

      signal: controller.signal

    })

 

    // 校验序列号,确保只处理最新请求的响应

    if (currentSeq !== requestSequence.get(url)) {

      console.log(

        `忽略过期响应: ${url} (当前序列号: ${currentSeq}, 最新序列号: ${requestSequence.get(url)})`

      )

      return

    }

 

    if (res?.data instanceof Blob) {

      const blobUrl = URL.createObjectURL(res.data)

      pictureUrlsRef.value[url] = blobUrl // 缓存结果

      return blobUrl

    }

  } catch (error) {

    // 忽略主动取消的错误

    if ((error as Error).name !== 'AbortError') {

      console.error('图片加载失败:', error)

    }

  } finally {

    // 清理状态(仅当前请求是最新的才执行)

    if (currentSeq === requestSequence.get(url)) {

      loadingUrls.delete(url)

      pendingRequests.delete(url)

    }

  }

}

 

export const clearImageCache = (pictureUrlsRef: { value: Record<string, string> }) => {

  Object.values(pictureUrlsRef.value).forEach((url) => {

    if (url.startsWith('blob:')) {

      URL.revokeObjectURL(url)

    }

  })

  pictureUrlsRef.value = {}

  requestSequence.clear() // 重置序列号

}`


//vue页面内使用


    

import { getImageUrl, loadingUrls, clearImageCache } from '@/utils/transitionImage'

 

 


const pictureUrls = ref<Record<string, string>>({})

 

 

const schema2 = reactive<DescriptionsSchema[]>([

{

    field: 'vehiclePicUri',

    label: '通行抓拍图',

    width: 100,

    slots: {

      default: (data: any) => {

        const imageUrl = data.vehiclePicUri

        const imgUrl = pictureUrls.value[imageUrl]

        const isLoading = Array.from(loadingUrls).includes(imageUrl)

        if (imageUrl && !imgUrl && !isLoading) {

          getImageUrl(imageUrl, pictureUrls)

        }

        return imgUrl ? (

          <ElImage

            style="width: 100px; height: 100px"

            src={imgUrl}

            zoom-rate={1.2}

            max-scale={7}

            min-scale={0.2}

            preview-src-list={[imgUrl]}

            initial-index={0}

            fit="cover"

          />

        ) : isLoading ? (

          <div class="flex items-center justify-center h-full">

            <i class="el-icon-loading"></i>

          </div>

        ) : (

          <div>(未知)</div>

        )

      }

    }

  }

])

 

 

 

// 监听弹窗打开,触发图片加载

watch(

  () => dialogVisible2.value,

  (newVal) => {

    if (newVal && data1) {

      const imageUrl = data1.vehiclePicUri

      if (imageUrl) {

        getImageUrl(imageUrl, pictureUrls)

      }

    }

  }

)

 

// 组件卸载时清理缓存,防止内存泄漏

onUnmounted(() => {

  clearImageCache(pictureUrls)

})

    



该文章在 2025/12/2 11:13:18 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved