AWS CDN+Lambda@Edge配置后JS文件MIME类型异常问题求助
CloudFront+Lambda@Edge导致JS文件MIME类型错误的解决思路
问题背景
使用AWS CloudFront搭配S3存储桶作为源站,未附加Origin Request阶段的Lambda@Edge函数时系统运行正常。添加用于路由重定向的Lambda@Edge后,出现JS文件的MIME类型被识别为text/html而非text/javascript的问题。
现有Lambda@Edge代码
'use strict'; exports.handler = (evt, context, cb) => { const { request } = evt.Records[0].cf; const uriParts = request.uri.split("/")[1]; const locales = ['en-US', 'ja', 'ms']; if (!uriParts || !locales.includes(uriParts)) { request.uri = '/en-US/index.html'; return cb(null, request) } request.uri = `/${uriParts}/index.html`; console.log(`Request Uri: ${request.uri}`); cb(null, request); }
架构配置
S3 Bucket en-US/ index.html <Angular生成的JS文件> ja/ index.html <Angular生成的JS文件> ms/ index.html <Angular生成的JS文件> CloudFront 分发配置,源站为上述S3存储桶
问题原因
当前Lambda函数的逻辑会强制所有请求重定向到对应locale的index.html,包括JS、CSS等静态资源请求。例如:
- 当请求
/en-US/main.js时,uriParts为en-US(属于locale列表),Lambda会将请求URI修改为/en-US/index.html - CloudFront从S3获取的是HTML文件,因此返回的MIME类型为
text/html,而非JS文件应有的text/javascript
解决方案
修改Lambda逻辑,仅对无文件扩展名的路径执行路由重定向,跳过带有扩展名的静态资源请求:
'use strict'; exports.handler = (evt, context, cb) => { const { request } = evt.Records[0].cf; const uri = request.uri; // 匹配带有文件扩展名的请求(如.js、.css、.png等),直接放行 const hasFileExtension = /\.\w+$/.test(uri); if (hasFileExtension) { return cb(null, request); } const uriParts = uri.split("/")[1]; const locales = ['en-US', 'ja', 'ms']; if (!uriParts || !locales.includes(uriParts)) { request.uri = '/en-US/index.html'; return cb(null, request); } request.uri = `/${uriParts}/index.html`; console.log(`Request Uri: ${request.uri}`); cb(null, request); };
逻辑说明
- 通过正则表达式
/\.\w+$/.test(uri)判断请求是否带有文件扩展名 - 若为静态资源请求(带扩展名),直接返回原请求,不修改URI
- 仅对无扩展名的路径(如根路径、
/en-US等)执行原有的路由重定向逻辑
这样既满足了多语言路由的需求,又能让静态资源正常从S3获取正确的MIME类型。
内容的提问来源于stack exchange,提问作者rodentskie
相关产品推荐
相关产品推荐

