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

使用swagger-ui-express动态加载YAML渲染SwaggerUI时空白页问题

问题:Express中使用swagger-ui-express动态加载OpenAPI文档出现空白页

我用ExpressJS搭配swagger-ui-express渲染SwaggerUI时,访问/api-docs/prd路由一直显示空白页。需求是每次访问这个路由时,先从云端下载YAML文件、解析成JSON格式后再传递给SwaggerUI。

可正常运行的提前加载代码

提前下载好文档再挂载路由的写法是没问题的:

const downloadAsYAML = async () => {
  const bucket ='buc';
  const path = 'openapi_prd.yaml';
 const file = await new Storage()
   .bucket(bucket)
   .file(path)
   .download();
  var x = yaml.parse(file[0].toString('utf8'))
  return x;
}

downloadAsYAML().then((res)=>{
app.use('/api-docs/prd', swaggerUi.serveFiles(res, options), swaggerUi.setup(null,options));
});

动态加载时的问题

改成在GET路由里动态下载文件的写法后,页面直接空白,控制台报这些错:

Refused to apply style from 'http://localhost:3001/api-docs/prd/swagger-ui.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

swagger-ui-bundle.js:1   Failed to load resource: the server responded with a status of 404 (Not Found) localhost/:1 Refused to execute script from 

对应的问题代码:

app.get('/api-docs/prd', function(req, res, next){
  downloadAsYAML('openapi_prd.yaml').then((result)=>{
    swaggerDocument=result;  //swaggerDocument初始值为null
  });
  next();
}, swaggerUi.serveFiles(swaggerDocument, options), swaggerUi.setup());

问题原因

  1. 异步代码顺序错误:downloadAsYAML是异步函数,调用后立刻执行next(),此时swaggerDocument还是初始的null值,swaggerUi.serveFiles拿到空参数后,无法正确加载SwaggerUI所需的静态资源(css、js),导致404和MIME类型错误。
  2. 中间件初始化是一次性的:app.get中的swaggerUi.serveFiles和swaggerUi.setup在服务启动时就已初始化,不会随每次请求重新执行,后续swaggerDocument赋值也无法更新中间件配置。

解决方法

要在请求处理流程中完成文件下载与解析,再动态调用SwaggerUI的渲染逻辑,确保每次请求都使用最新文档:

调整后的代码

首先修改downloadAsYAML让它支持接收文件名参数:

const downloadAsYAML = async (fileName) => {
  const bucket = 'buc';
  const path = fileName;
  const file = await new Storage()
    .bucket(bucket)
    .file(path)
    .download();
  return yaml.parse(file[0].toString('utf8'));
};

然后修改路由处理逻辑:

app.get('/api-docs/prd', async (req, res, next) => {
  try {
    // 先完成文档的下载和解析
    const swaggerDocument = await downloadAsYAML('openapi_prd.yaml');
    // 用最新文档调用setup并处理请求
    swaggerUi.setup(swaggerDocument, options)(req, res, next);
  } catch (err) {
    next(err); // 处理下载或解析时的错误
  }
}, swaggerUi.serveFiles(null, options));

代码说明

  • 使用async/await确保文档下载完成后再渲染SwaggerUI,彻底解决异步顺序问题。
  • swaggerUi.serveFiles传入null,因为我们会在请求时动态传入文档,无需提前指定。
  • 将swaggerUi.setup放在请求回调内,每次请求都基于最新下载的文档初始化SwaggerUI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:24:58