如何实现后端作为前端与外部服务器的文件获取桥梁?
解决方案
1. 修正控制器路由与参数接收
首先将控制器路由改为动态参数匹配,适配前端请求的URL结构,同时正确处理不同类型的文件返回:
import { Controller, Get, Param, StreamableFile, Response } from '@nestjs/common'; import { GeomService } from './geom.service'; @Controller() export class GeomController { constructor(private readonly geomService: GeomService) {} // 匹配动态路径:/geometrictiles/{layername}/{z}/{x}/{y}.{ext} @Get('/geometrictiles/:layername/:z/:x/:y.:ext') async getGeoTiles( @Param('layername') layername: string, @Param('z') z: string, @Param('x') x: string, @Param('y') y: string, @Param('ext') ext: string, @Response() res, ) { const fileData = await this.geomService.getGeometricFile(layername, z, x, y, ext); // 根据扩展名设置响应Content-Type res.setHeader('Content-Type', this.getContentType(ext)); if (['pbf', 'jpg', 'pdf'].includes(ext.toLowerCase())) { return new StreamableFile(fileData); } else { res.send(fileData); } } // 辅助方法:映射扩展名到对应Content-Type private getContentType(ext: string): string { const typeMap = { pbf: 'application/x-protobuf', jpg: 'image/jpeg', pdf: 'application/pdf', csv: 'text/csv', json: 'application/json', }; return typeMap[ext.toLowerCase()] || 'application/octet-stream'; } }
2. 重构服务层方法,适配多文件类型
服务层需根据文件类型设置响应类型,确保获取原始数据不被篡改:
import { Injectable, ForbiddenException } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { catchError, map } from 'rxjs/operators'; @Injectable() export class GeomService { private readonly privateServerBase = 'http://XXX.XXX.XXX.XXX/geometrictiles'; constructor(private readonly httpService: HttpService) {} async getGeometricFile( layername: string, z: string, x: string, y: string, ext: string, ) { const targetUrl = `${this.privateServerBase}/${layername}/${z}/${x}/${y}.${ext}`; // 二进制文件用stream模式,文本类用json模式 const responseType = ['pbf', 'jpg', 'pdf'].includes(ext.toLowerCase()) ? 'stream' : 'json'; return this.httpService.get(targetUrl, { responseType }) .pipe( map(res => responseType === 'stream' ? res.data : res.data), catchError(() => { throw new ForbiddenException('私有地图服务器请求失败'); }), ) .toPromise(); } }
3. 关键修复点说明
- 动态路由:通过
:layername、:z等占位符,完美匹配前端请求的URL结构,无需硬编码参数。 - 响应类型适配:二进制文件(PBF、JPG、PDF)使用
stream响应类型,避免JSON解析导致文件损坏;文本类(JSON、CSV)直接获取原始数据。 - Content-Type设置:正确设置响应头,让前端能识别文件类型并正确处理。
- 错误统一处理:捕获私有服务器请求异常,返回明确的错误信息。
4. 测试验证
- JSON测试:请求
http://localhost:3001/geometrictiles/mylayer/11/585/783.json,应返回私有服务器对应JSON数据。 - PBF测试:请求
http://localhost:3001/geometrictiles/mylayer/11/585/783.pbf,应返回原始二进制文件,可通过地图工具验证完整性。 - 图片测试:请求
http://localhost:3001/geometrictiles/mylayer/11/585/783.jpg,浏览器应直接显示图片。
内容的提问来源于stack exchange,提问作者Jorge Monroy
相关产品推荐
相关产品推荐

