Swagger UI部署Vercel出现Unexpected token < in JSON at position 1错误
代码
完整代码库与目录结构可在GitHub查看
以下是Swagger相关路由(需作为独立服务运行)
// api/v1.ts import express = require("express"); import swaggerJSDoc = require("swagger-jsdoc"); import swaggerUi = require("swagger-ui-express"); import packageJSON = require("../package.json"); import path = require("path"); const app = express(); app.use(express.json()); app.use(express.static(path.resolve(__dirname, "../", "public"))); const swaggerSpec = swaggerJSDoc({ swaggerDefinition: some_spec, apis: ["api/*"] }); const cssOpts = some_css_override; app.use("/api/v1", swaggerUi.serve, swaggerUi.setup(swaggerSpec, cssOpts)); module.exports = app;
问题描述
本地运行vercel dev时,访问localhost:3000/api/v1可正常查看Swagger文档:
但将代码推送至分支触发Vercel构建后,线上访问出现异常:
查看控制台可见如下报错:
DevTools failed to load source map: Could not parse content for https://colormaster-1unjfn63b-lbragile.vercel.app/api/v1/swagger-ui-bundle.js.map: Unexpected token < in JSON at position 1 DevTools failed to load source map: Could not parse content for https://colormaster-1unjfn63b-lbragile.vercel.app/api/v1/swagger-ui-standalone-preset.js.map: Unexpected token < in JSON at position 1
上述请求的响应状态码均为200:
我已知该错误与尝试对HTML内容执行JSON.parse()有关,但不清楚具体修复方案,请问该如何解决?
原因分析
报错的核心原因是Vercel无服务函数的路由匹配逻辑问题:当浏览器请求/api/v1路径下的静态资源(如swagger所需的js、css、map文件)时,所有请求都被匹配到了返回swagger HTML页面的路由上,导致静态资源请求实际返回的是HTML内容,浏览器尝试把HTML当作JS/JSON解析就会抛出对应错误,同时swagger页面也无法正常加载。
修复方案
方案一:配置Vercel路由重写+调整静态资源挂载(推荐,可彻底解决问题)
- 项目根目录新增/修改
vercel.json,添加重写规则,确保/api/v1下的所有子路径请求都打到你的swagger服务入口:
{ "rewrites": [ { "source": "/api/v1/(.*)", "destination": "/api/v1.ts" } ] }
- 修改
api/v1.ts代码,挂载swagger官方静态资源目录,确保静态资源请求能返回正确文件:
// 新增导入,获取swagger-ui静态资源目录 const swaggerUiAssetPath = require('swagger-ui-dist').getAbsoluteFSPath(); const app = express(); app.use(express.json()); app.use(express.static(path.resolve(__dirname, "../", "public"))); // 新增:挂载swagger静态资源 app.use("/api/v1", express.static(swaggerUiAssetPath)); // 原有swagger配置逻辑保持不变 const swaggerSpec = swaggerJSDoc({ swaggerDefinition: some_spec, apis: ["api/*"] }); const cssOpts = some_css_override; app.use("/api/v1", swaggerUi.serve, swaggerUi.setup(swaggerSpec, cssOpts)); module.exports = app;
方案二:快速禁用source map(临时解决,不影响swagger正常使用)
如果不需要调试swagger源码,可直接在swagger初始化配置中关闭source map加载,跳过报错:
app.use("/api/v1", swaggerUi.serve, swaggerUi.setup(swaggerSpec, { ...cssOpts, swaggerOptions: { sourceMap: false } }));
内容的提问来源于stack exchange,提问作者lbragile
相关产品推荐
相关产品推荐

