最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端獲取二進(jìn)制文件并預(yù)覽功能的完整指南

 更新時間:2026年02月02日 09:22:24   作者:裴清禾  
前后端對接時,后端常有返回二進(jìn)制流文件的情況,前端需要下載或預(yù)覽(pdf、html、圖片文件等),這篇文章主要介紹了前端獲取二進(jìn)制文件并預(yù)覽功能的相關(guān)資料,需要的朋友可以參考下

前言

在前端開發(fā)中,我們經(jīng)常需要處理后端返回的二進(jìn)制文件,比如PDF、圖片、Excel等。本文將詳細(xì)介紹如何在前端獲取二進(jìn)制文件并實(shí)現(xiàn)預(yù)覽功能。

一、什么是二進(jìn)制文件?

二進(jìn)制文件是以二進(jìn)制格式存儲的文件,與文本文件不同,它不能直接以文本形式查看。常見的二進(jìn)制文件包括:

  • PDF文檔
  • 圖片(JPG、PNG、GIF等)
  • Office文檔(Word、Excel、PPT)
  • 壓縮包(ZIP、RAR)
  • 音視頻文件

二、后端接口配置

1. 后端返回二進(jìn)制數(shù)據(jù)

后端需要設(shè)置正確的響應(yīng)頭:

// Spring Boot 示例
@PostMapping("/previewPDF")
public ResponseEntity<byte[]> previewPDF(@RequestBody Map<String, Object> params) {
    byte[] pdfBytes = pdfService.generatePDF(params);
    
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_PDF);
    headers.setContentDispositionFormData("inline", "preview.pdf");
    
    return new ResponseEntity<>(pdfBytes, headers, HttpStatus.OK);
}

2. 前端接口定義

使用axios時,需要設(shè)置responseType: 'blob'

// api/file.js
import request from '@/utils/request'

export function previewPDF(data) {
    return request({
        url: '/api/pdf/preview',
        method: 'post',
        data: data,
        responseType: 'blob'  // 關(guān)鍵配置:告訴axios以二進(jìn)制方式接收數(shù)據(jù)
    })
}

三、前端處理二進(jìn)制數(shù)據(jù)

1. 基礎(chǔ)概念

Blob對象:Blob(Binary Large Object)表示一個不可變的、原始數(shù)據(jù)的類文件對象。

URL.createObjectURL():創(chuàng)建一個指向Blob對象的臨時URL。

2. 完整實(shí)現(xiàn)代碼

// 預(yù)覽PDF的完整方法
async previewPDF() {
    try {
        // 1. 顯示加載提示
        const loading = this.$loading({
            lock: true,
            text: '正在生成預(yù)覽...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)'
        })

        // 2. 調(diào)用接口獲取二進(jìn)制數(shù)據(jù)
        const blob = await previewPDF({
            id: this.reportId,
            type: 'preview'
        })

        // 3. 創(chuàng)建Blob對象
        const pdfBlob = new Blob([blob], { 
            type: 'application/pdf' 
        })

        // 4. 創(chuàng)建臨時URL
        const blobUrl = window.URL.createObjectURL(pdfBlob)

        // 5. 在新窗口中打開
        window.open(blobUrl, '_blank')

        // 6. 延遲釋放URL(給瀏覽器足夠時間加載)
        setTimeout(() => {
            window.URL.revokeObjectURL(blobUrl)
        }, 100)

        loading.close()
        this.$message.success('PDF預(yù)覽已打開')

    } catch (error) {
        console.error('預(yù)覽失敗:', error)
        this.$message.error('預(yù)覽失敗,請重試')
    }
}

四、不同文件類型的處理

1. PDF文件預(yù)覽

// PDF預(yù)覽
function previewPDF(blob) {
    const pdfBlob = new Blob([blob], { type: 'application/pdf' })
    const url = window.URL.createObjectURL(pdfBlob)
    window.open(url, '_blank')
    setTimeout(() => window.URL.revokeObjectURL(url), 100)
}

2. 圖片預(yù)覽

// 圖片預(yù)覽
function previewImage(blob) {
    const imageBlob = new Blob([blob], { type: 'image/jpeg' })
    const url = window.URL.createObjectURL(imageBlob)
    
    // 方式1:新窗口打開
    window.open(url, '_blank')
    
    // 方式2:在img標(biāo)簽中顯示
    const img = document.createElement('img')
    img.src = url
    document.body.appendChild(img)
    
    // 記得釋放URL
    img.onload = () => {
        window.URL.revokeObjectURL(url)
    }
}

3. Excel文件下載

// Excel下載
function downloadExcel(blob, filename) {
    const excelBlob = new Blob([blob], { 
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
    })
    const url = window.URL.createObjectURL(excelBlob)
    
    // 創(chuàng)建a標(biāo)簽觸發(fā)下載
    const link = document.createElement('a')
    link.href = url
    link.download = filename || 'download.xlsx'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    
    // 釋放URL
    window.URL.revokeObjectURL(url)
}

4. Word文檔下載

// Word下載
function downloadWord(blob, filename) {
    const wordBlob = new Blob([blob], { 
        type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' 
    })
    const url = window.URL.createObjectURL(wordBlob)
    
    const link = document.createElement('a')
    link.href = url
    link.download = filename || 'document.docx'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    
    window.URL.revokeObjectURL(url)
}

五、常見MIME類型對照表

文件類型MIME類型
PDFapplication/pdf
JPG/JPEGimage/jpeg
PNGimage/png
GIFimage/gif
Excel (.xlsx)application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Excel (.xls)application/vnd.ms-excel
Word (.docx)application/vnd.openxmlformats-officedocument.wordprocessingml.document
Word (.doc)application/msword
ZIPapplication/zip
TXTtext/plain

六、Vue完整示例

<template>
    <div>
        <el-button @click="handlePreview" type="primary">預(yù)覽PDF</el-button>
        <el-button @click="handleDownload" type="success">下載PDF</el-button>
    </div>
</template>

<script>
import { previewPDF } from '@/api/file'

export default {
    data() {
        return {
            fileId: '123456'
        }
    },
    methods: {
        // 預(yù)覽
        async handlePreview() {
            try {
                const loading = this.$loading({
                    lock: true,
                    text: '正在加載...'
                })

                const blob = await previewPDF({ id: this.fileId })
                const url = window.URL.createObjectURL(
                    new Blob([blob], { type: 'application/pdf' })
                )
                
                window.open(url, '_blank')
                
                setTimeout(() => {
                    window.URL.revokeObjectURL(url)
                }, 100)

                loading.close()
            } catch (error) {
                this.$message.error('預(yù)覽失敗')
            }
        },

        // 下載
        async handleDownload() {
            try {
                const loading = this.$loading({
                    lock: true,
                    text: '正在下載...'
                })

                const blob = await previewPDF({ id: this.fileId })
                const url = window.URL.createObjectURL(
                    new Blob([blob], { type: 'application/pdf' })
                )
                
                const link = document.createElement('a')
                link.href = url
                link.download = 'report.pdf'
                document.body.appendChild(link)
                link.click()
                document.body.removeChild(link)
                
                window.URL.revokeObjectURL(url)

                loading.close()
                this.$message.success('下載成功')
            } catch (error) {
                this.$message.error('下載失敗')
            }
        }
    }
}
</script>

七、常見問題及解決方案

1. 問題:接口返回亂碼

原因:沒有設(shè)置responseType: 'blob'

解決

// 錯誤寫法
export function previewPDF(data) {
    return request({
        url: '/api/pdf/preview',
        method: 'post',
        data: data
        // 缺少 responseType: 'blob'
    })
}

// 正確寫法
export function previewPDF(data) {
    return request({
        url: '/api/pdf/preview',
        method: 'post',
        data: data,
        responseType: 'blob'  // 必須添加
    })
}

2. 問題:PDF在新窗口無法打開

原因:瀏覽器攔截了彈窗

解決

// 方式1:提示用戶允許彈窗
window.open(url, '_blank')

// 方式2:使用iframe在當(dāng)前頁面顯示
const iframe = document.createElement('iframe')
iframe.src = url
iframe.style.width = '100%'
iframe.style.height = '600px'
document.body.appendChild(iframe)

3. 問題:內(nèi)存泄漏

原因:創(chuàng)建的URL沒有及時釋放

解決

// 記得釋放URL
const url = window.URL.createObjectURL(blob)
// ... 使用URL
window.URL.revokeObjectURL(url)  // 使用完后釋放

4. 問題:下載的文件名亂碼

解決

// 從響應(yīng)頭獲取文件名
function getFileNameFromResponse(response) {
    const disposition = response.headers['content-disposition']
    if (disposition) {
        const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(disposition)
        if (matches && matches[1]) {
            return decodeURIComponent(matches[1].replace(/['"]/g, ''))
        }
    }
    return 'download.pdf'
}

八、性能優(yōu)化建議

1. 大文件處理

// 對于大文件,使用流式下載
async function downloadLargeFile(url) {
    const response = await fetch(url)
    const reader = response.body.getReader()
    const chunks = []
    
    while (true) {
        const { done, value } = await reader.read()
        if (done) break
        chunks.push(value)
    }
    
    const blob = new Blob(chunks)
    // 處理blob...
}

2. 添加進(jìn)度提示

async function downloadWithProgress(url, onProgress) {
    const response = await fetch(url)
    const total = response.headers.get('content-length')
    const reader = response.body.getReader()
    
    let loaded = 0
    const chunks = []
    
    while (true) {
        const { done, value } = await reader.read()
        if (done) break
        
        chunks.push(value)
        loaded += value.length
        
        if (onProgress) {
            onProgress({ loaded, total })
        }
    }
    
    return new Blob(chunks)
}

九、總結(jié)

處理二進(jìn)制文件的關(guān)鍵步驟:

  1. 接口配置:設(shè)置responseType: 'blob'
  2. 創(chuàng)建Blobnew Blob([data], { type: 'mime-type' })
  3. 創(chuàng)建URLURL.createObjectURL(blob)
  4. 使用URL:預(yù)覽或下載
  5. 釋放資源URL.revokeObjectURL(url)

掌握這些技巧,你就能輕松處理各種二進(jìn)制文件了!

參考資料

到此這篇關(guān)于前端獲取二進(jìn)制文件并預(yù)覽功能的完整指南的文章就介紹到這了,更多相關(guān)前端獲取二進(jìn)制文件預(yù)覽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

禹城市| 雅江县| 班玛县| 平谷区| 常德市| 沈阳市| 遂川县| 汉阴县| 茌平县| 博湖县| 长沙县| 江口县| 辉南县| 富顺县| 江西省| 江川县| 福建省| 依兰县| 大埔县| 榆社县| 吐鲁番市| 耿马| 乐清市| 莎车县| 依兰县| 喜德县| 吉木乃县| 武川县| 吴桥县| 苍山县| 南充市| 广平县| 宁阳县| 仪陇县| 深水埗区| 富平县| 马龙县| 铜梁县| 竹山县| 辽阳市| 海晏县|