使用JSZip压缩字体文件(例如:ArialMT.ttf)无法正常工作。

3
压缩图像和HTML文件正常工作,但添加用于CSS的字体文件时,字体文件大小为1kb且无法打开。
我尝试仅压缩字体,没有其他文件,但仍然存在相同的问题。
let zip = new JSZip()
let imageURLCount = 0
let fontFileCount = 0

let imageURLs = [
 'http:site.com/image1.jpg',
 'http:site.com/image2.jpg',
 'http:site.com/image3.jpg',
 'http:site.com/image4.jpg'
]

let fontFiles = [
 'http:site.com/fontFile1.ttf',
 'http:site.com/fontFile2.ttf',
 'http:site.com/fontFile3.ttf',
 'http:site.com/fontFile4.ttf'
]

// zip images
imageURLs.forEach((url, i) => {
  JSZipUtils.getBinaryContent(url, (error, data) => {
     if (error) {
        throw error
     }
     // zip file name
     imageFileName = 'image_'+i+'.jpg'

     // create images folder
     zip.folder('images')
        .file(imageFileName, data,{binary: true})

     imageURLCount++
     if (imageURLCount === imageURLs.length) {
        zipComplete(imageURLCount,fontFileCount)
     }
  })
}) // end imageURLs[] forEach 

// zip font files
fontFiles.forEach((fontFile, i) => {
  JSZipUtils.getBinaryContent(fontFile, (error, data) => {
     if (error) {
        throw error
     }

     // zip file name
     fileName = 'font_'+i+'.ttf'
     zip.file(fileName, data, {binary:true})
     fontFileCount++
     if (fontFileCount === fontFiles.length) {
        zipComplete(imageURLCount,fontFileCount)
     }
  })
}) // end fontFiles[] forEach 

// PS: zipComplete(imageURLCount,fontFileCount) checks if both arrays looped to the end and then trigger the 'file-saver' SaveAs()

我该如何压缩字体?使用JSZip可以吗?


你有确认变量 data 中真的包含了字体二进制数据而非其他内容吗?比如,在 URL 无效或出现 404 错误页面的情况下,它是否包含了错误页的 HTML 内容? - Patrick Evans
imageURLs.forEach((url, i) => {}) 中,zip 没有被构建。你的示例代码是否缺失了一些内容? - BlueWater86
@PatrickEvans 当我使用console.log(data)时,我得到的结果是: ArrayBuffer(97344) {} [[Int8Array]]: Int8Array(97344) [79, 84, 84, 79, …] [[Int16Array]]: Int16Array(48672) [21583, 20308, …] [[Int32Array]]: Int32Array(24336) [1330926671, -2147480320, 2157312, …] [[Uint8Array]]: Uint8Array(97344) [79, 84, …] byteLength: (...) - hatchDev
@BlueWater86 抱歉我错过了那部分(现在已添加)。奇怪的是我可以压缩图像、文本、远程服务器HTML、CSS和JS,但不能压缩字体。这是一个庞大的函数,所以我只想展示图像和字体“压缩”是以相同的方式处理的,而不是粘贴整个内容。谢谢! - hatchDev
难道是zip功能的SaveAs()在所有字体数据加载之前运行了吗? 你是如何加载字体的?使用XHR吗? - moonunit7
@moonunit7 - 是的,我正在使用xhr,甚至添加了一个巨大的setTimeout()来确保它不会太早运行。奇怪的是除了字体之外,一切都很顺利。所以我在想,字体文件是否需要不同的方法? - hatchDev
1个回答

1
我本来期望编辑你的示例并在你的代码中找到问题,但结果发现没有错。这里有一个工作示例,可以成功压缩.tff文件,然后下载zip文件。
我猜问题可能出在从你的.ttf URI返回的内容上。

let zip = new JSZip()
let imageURLCount = 0
let fontFileCount = 0

let imageURLs = []

let fontFiles = [
  'https://fontlibrary.org/assets/fonts/symbola/cf81aeb303c13ce765877d31571dc5c7/7d8d51a2e1b57d59075325384458fac6/SymbolaRegular.ttf'
]

// zip font files
fontFiles.forEach((fontFile, i) => {
  JSZipUtils.getBinaryContent(fontFile, (error, data) => {
    if (error) {
      throw error
    }

    // zip file name
    fileName = 'font_' + i + '.ttf'
    zip.file(fileName, data, {
      binary: true
    })
    fontFileCount++
    if (fontFileCount === fontFiles.length) {
      zipComplete(imageURLCount, fontFileCount)
    }
  })
}) // end fontFiles[] forEach 
function zipComplete(imageURLCount, fontFileCount) {
  zip.generateAsync({
      type: "blob"
    })
    .then(function(content) {
      // see FileSaver.js
      saveAs(content, "example.zip");
    });
}
// PS: zipComplete(imageURLCount,fontFileCount) checks if both arrays looped to the end and then trigger the 'file-saver' SaveAs()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.2/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip-utils/0.1.0/jszip-utils.js"></script>
<script src="http://cdn.jsdelivr.net/g/filesaver.js"></script>


谢谢!这让我感到有希望:) 至少我知道问题不是JSZip。应该像你一样在项目之外运行代码‍♂️。 - hatchDev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接