Express+TypeScript中Swagger UI访问短URL路由出现NetworkError
错误:TypeError: 尝试获取资源时发生网络错误
访问路由http://localhost:4001/api/4a7ed517时,该路由在浏览器地址栏、Insomnia等HTTP客户端中均可正常跳转,但在Swagger UI中调用会触发上述网络错误,其余所有路由均正常工作。


调用生成的短URL时出现该问题,寻求解决方法。
相关代码
Mongoose Schema定义
const urlSchema = new Schema<IUrl>( { shortID: { type: String, required: true, unique: true, }, redirectURL: { type: String, required: true, }, visitHistory: [{ timestamp: { type: Number } }], }, { timestamps: true } );
OpenAPI 3.0配置
{ "openapi": "3.0.0", "info": { "title": "URL Shortener API", "description": "API for shortening URLs and retrieving analytics", "version": "1.0.0", "license": { "name": "MIT", "url": "https://opensource.org/licenses/MIT" } }, "paths": { "/api/generate": { "post": { "summary": "Generate Short URL", "description": "Generates a new short URL for the provided long URL.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "url": { "type": "string", "description": "The original long URL to be shortened." } }, "required": ["url"] } } } }, "responses": { "201": { "description": "Short URL generated successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "url": { "type": "string", "description": "The generated short URL." } } } } } } }, "tags": [ "Short URL" ] } }, "/api/{shortID}": { "get": { "summary": "Redirect to the original URL using the short ID", "parameters": [ { "in": "path", "name": "shortID", "required": true, "description": "The short ID associated with the URL", "schema": { "type": "string" } } ], "responses": { "302": { "description": "Redirect to the original URL" }, "404": { "description": "Short ID not found" } }, "tags": [ "Redirect" ] } }, "/api/analytics/{shortID}": { "get": { "summary": "Get Analytics for Short URL", "description": "Retrieves analytics data for a specific short URL, including visit history.", "parameters": [ { "name": "shortID", "in": "path", "required": true, "description": "Short identifier for the URL.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Successfully retrieved analytics data.", "content": { "application/json": { "schema": { "type": "object", "properties": { "redirectURL": { "type": "string", "description": "The short URL." }, "url": { "type": "string", "description": "The original long URL." }, "visitHistory": { "type": "array", "items": { "type": "object", "properties": { "timestamp": { "type": "integer", "description": "Visit timestamp." } } } } } } } } }, "404": { "description": "URL not found." } }, "tags": [ "Analytics" ] } } } }
问题原因
Swagger UI依赖浏览器的Fetch API发送请求,而Fetch API默认不会自动跨域跟随302重定向。当短URL重定向到外部第三方网站时,浏览器的CORS策略会阻止Swagger UI完成请求,从而触发NetworkError。而浏览器地址栏或Insomnia这类工具是直接发起导航请求,不受Fetch API的跨域限制,因此可以正常跳转。
解决办法
方案1:修改OpenAPI文档提示用户
在/api/{shortID}接口的summary或description中明确说明:该接口用于浏览器地址栏跳转,Swagger UI中调用仅用于验证存在性,如需跳转请复制完整URL到地址栏访问。
方案2:后端适配Swagger UI请求
检测请求的User-Agent是否包含Swagger关键字,若为Swagger UI的请求,则返回JSON格式的原URL而非302重定向。示例代码(Express为例):
app.get('/api/:shortID', async (req, res) => { const { shortID } = req.params; const urlDoc = await URLModel.findOne({ shortID }); if (!urlDoc) return res.status(404).json({ error: 'Short ID not found' }); // 记录访问历史 await URLModel.findOneAndUpdate( { shortID }, { $push: { visitHistory: { timestamp: Date.now() } } } ); // 判断是否来自Swagger UI const isSwagger = req.get('User-Agent')?.includes('Swagger'); if (isSwagger) { return res.json({ originalUrl: urlDoc.redirectURL }); } // 正常重定向 res.redirect(urlDoc.redirectURL); });
方案3:调整Swagger UI配置(有限适用)
如果重定向目标是同域名下的地址,可以在Swagger UI的初始化配置中开启fetch的redirect: 'follow'选项,但此方法对跨域外部URL无效,因为浏览器CORS策略会拦截响应。
内容的提问来源于stack exchange,提问作者Harsh Vardhan Pandey
相关产品推荐
相关产品推荐

