同一地址提供EC2静态内容与API Gateway REST服务的解决方案咨询
解决EC2静态站点与API Gateway跨域+统一访问地址方案
嘿,太懂你这种跨域折腾的痛苦了——不仅调试CORS要改一堆配置,用户访问还要记两个地址也不友好。你提到的两种思路都很靠谱,我给你拆解下具体怎么落地:
方案一:让EC2上的Express同时托管静态内容+代理API请求
这应该就是你说的“同时托管”的思路,利用Express的中间件把API请求转发到Gateway,实现同一域名访问:
- 首先,你应该已经在用Express托管静态文件了,比如:
app.use(express.static('public')); // 替换成你的静态文件目录 - 接下来,安装代理中间件
http-proxy-middleware,用来转发API请求:npm install http-proxy-middleware - 在Express中配置代理规则,把所有
/api开头的请求转发到你的API Gateway地址:const { createProxyMiddleware } = require('http-proxy-middleware'); // 配置API代理 app.use('/api', createProxyMiddleware({ target: 'https://your-api-gateway-id.execute-api.region.amazonaws.com', // 替换成你的API Gateway地址 changeOrigin: true, // 必须开启,解决跨域时的Origin校验问题 pathRewrite: { '^/api': '' // 如果你的API Gateway路径不带/api前缀,就把这个前缀移除 } })); - 这样一来,用户访问
https://your-ec2-domain.com会加载静态页面,访问https://your-ec2-domain.com/api/xxx就会被自动转发到API Gateway,完全避免了跨域问题,因为所有请求都来自同一域名。 - 注意事项:确保EC2安全组允许出站到API Gateway的443端口;如果用HTTPS,EC2上要配置好SSL证书(比如用Let's Encrypt),和API Gateway的协议保持一致。
方案二:用CloudFront做统一入口(生产环境首选)
这种方案不需要改动EC2的代码,通过CloudFront作为统一入口,把不同路径的请求路由到对应的源,扩展性和安全性更好:
- 第一步:创建CloudFront分发器,添加两个源:
- 源1:指向你的EC2域名(或ELB,如果有负载均衡),对应静态内容的默认路径
- 源2:指向你的API Gateway域名,对应API请求路径
- 第二步:配置CloudFront行为(Behaviors):
- 为
/api/*创建单独的行为,将请求转发到API Gateway源;如果是动态API,记得把缓存策略设为不缓存,或者根据请求参数配置合理的缓存规则 - 默认行为(
/*)转发到EC2源,开启静态文件缓存以提升加载速度
- 为
- 第三步:把你的主域名通过Route 53的CNAME记录指向CloudFront的分发域名
- 优势:CloudFront自带全球CDN加速,静态内容加载更快;可以通过AWS Certificate Manager统一管理SSL证书;还能集成WAF做安全防护,比直接暴露EC2更可靠。
- 注意事项:API Gateway需要配置允许CloudFront的域名作为CORS的
AllowedOrigin(生产环境不建议用*,指定具体域名更安全);CloudFront行为中要确保转发必要的请求头(比如Origin、Authorization)给API Gateway。
两种方案都能完美解决你的问题,小项目快速迭代选方案一,生产环境追求高可用和性能选方案二~
内容的提问来源于stack exchange,提问作者Mehran
相关产品推荐
相关产品推荐

