You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Netlify部署Express应用时无法加载图片与字体的问题排查

Netlify部署Express应用:图片与字体资源加载失败问题解决

问题描述

编程新手首次在Netlify部署Node.js+Express应用,HTML、CSS、JavaScript可正常运行,但Express无法提供图片与字体资源。控制台报错:

Failed to decode downloaded font:
http://localhost:8888/styles/fonts/Norms/NormsProMedium.ttf
localhost/:1 OTS parsing error: DSIG: misaligned table
localhost/:1 Failed to decode downloaded font:

现有代码与配置

Express代码

require('dotenv').config();
const express = require('express');
const serverless = require('serverless-http');
const path = require('path');
const app = express();

const router = express.Router();

const cors = require('cors');


app.use(cors());



app.use(express.json());


router.get('/products.json', (req, res) => {
    res.sendFile(path.join(__dirname, '/public/products.json'));
});

router.get('/products.json', (req, res) => {
    res.sendFile(path.join(__dirname, '/public/products.json'));
});

router.use(express.static(path.join(__dirname, '../public/styles/fonts')));

 router.use(express.static(path.join(__dirname, '../public/images')));

router.use(express.static(path.join(__dirname, '../public'), {
    setHeaders: (res, filePath) => {
        const ext = path.extname(filePath);
        const mimeTypes = {
            '.html': 'text/html',
            '.js': 'application/javascript',
            '.css': 'text/css',
        };
        const contentType = mimeTypes[ext];
        if (contentType) {
            res.setHeader('Content-Type', contentType);
        }
    }
}));


router.use(express.static(path.join(__dirname, '../public/styles/fonts'), {
    setHeaders: (res, filePath) => {
      const ext = path.extname(filePath);
      const mimeTypes = {
        '.ttf': 'application/font-ttf',
        '.otf': 'application/font-otf',
        '.eot': 'application/vnd.ms-fontobject',
        '.woff': 'application/font-woff',
        '.woff2': 'application/font-woff2',
        '.svg': 'image/svg+xml',
      };
      const contentType = mimeTypes[ext];
      if (contentType) {
        res.setHeader('Content-Type', contentType);
      }
    }
  }));


router.get("", (req, res) => {
    res.sendFile(path.join(__dirname, '../public/views', 'index.html'));
});



app.use('/', router);

module.exports.handler = serverless(app);

netlify.toml配置

[build]
   functions="functions"

[[redirects]]
  to="/.netlify/functions/api/:splat"
  from="/*"
  status=200

问题分析与解决方案

1. 静态资源路径冲突与冗余配置

重复配置了../public/styles/fonts的静态服务,路径优先级易导致资源加载异常;同时__dirname在Netlify函数环境中的指向与本地不同,易引发路径错误。

修复:

  • 移除单独的fonts和images静态配置,仅保留顶层public目录的静态服务,统一处理所有静态资源。
  • 合并MIME类型配置,避免重复逻辑。

修改后的静态资源处理代码:

// 移除单独的fonts、images静态配置,保留顶层public的静态服务
router.use(express.static(path.join(__dirname, '../public'), {
    setHeaders: (res, filePath) => {
        const ext = path.extname(filePath);
        // 合并所有资源的MIME类型配置
        const mimeTypes = {
            '.html': 'text/html',
            '.js': 'application/javascript',
            '.css': 'text/css',
            '.ttf': 'font/ttf', // 替换非标准MIME类型为标准值
            '.otf': 'font/otf',
            '.eot': 'application/vnd.ms-fontobject',
            '.woff': 'font/woff',
            '.woff2': 'font/woff2',
            '.svg': 'image/svg+xml',
            '.png': 'image/png', // 添加图片类型的MIME配置
            '.jpg': 'image/jpeg',
            '.gif': 'image/gif'
        };
        const contentType = mimeTypes[ext];
        if (contentType) {
            res.setHeader('Content-Type', contentType);
        }
    }
}));

2. 字体MIME类型错误

原代码使用的application/font-ttf等非标准MIME类型,可能导致浏览器解析字体失败,需替换为font/ttf、font/woff等标准类型。

3. Netlify重定向与函数路径匹配

确保Express函数文件放在functions/api目录下(对应netlify.toml中的配置),若函数文件名不是api.js,需调整重定向规则中的路径。例如函数文件为index.js时,重定向规则改为:

[[redirects]]
  to="/.netlify/functions/index/:splat"
  from="/*"
  status=200

4. 字体文件本身问题

若上述调整后仍报错,可能是字体文件损坏。可尝试重新替换字体文件,或用工具(如FontSquirrel)重新生成并移除DSIG签名(部分浏览器对异常DSIG签名会触发解析错误)。

总结

按上述步骤调整代码与配置后,重新部署到Netlify即可解决图片与字体资源的加载问题。

内容的提问来源于stack exchange,提问作者Pcelarnik Danevi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:40:40