基于Next.js 13与SST,实现CloudFront外部URL重写的方案咨询
背景
我有一个基于CRA React的大型仓库,需要为SSR添加SEO功能。因此创建了一个新的Next.js 13仓库,仅将需要SEO功能的页面(如着陆页)放在其中,希望通过URL重写实现增量迁移,让用户无感知。
需求目标
需要实现简单的外部URL重写:https://my-domain.com/company → https://my-domain-legacy.com/company
仓库与基础设施
创建了一个仅包含index路由的空Next.js 13项目,通过SST部署。已知Next.js提供rewrites功能,但目前SST仅支持内部URL重写,不支持外部URL重写。
问题
有什么方案可以实现需求?比如替代SST的工具,或通过Lambda@Edge/CloudFront函数实现的方法?
已尝试操作
尝试在Lambda@Edge函数中创建简单的内部URL重写:
exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; request.uri = request.uri .replace(/\/company$/,'/'); return callback(null, request); };
但访问Next.js路由中不存在的页面时,始终返回AccessDenied错误。
补充说明1
当前的函数代码:
exports.handler = (event, context, callback) => { console.log(event); const request = event.Records[0].cf.request; // request.uri = request.uri // .replace(/\/company$/,'/'); request.origin.custom.domainName = "https://my-domain-legacy.com" return callback(null, request); };
使用上述Lambda函数时出现请求失败的错误,当前Lambda@Edge已配置基础执行权限。
可行解决方案
1. 修正Lambda@Edge函数实现外部重写
你的Lambda@Edge代码存在两处关键问题:
- 设置
origin.custom.domainName时不能带https://,只需填写纯域名 - 未正确配置源的协议和请求头,导致CloudFront无法正确转发请求
修改后的函数代码如下:
exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; const uri = request.uri; // 匹配需要重写的路径,支持/company及子路径 if (uri === '/company' || uri.startsWith('/company/')) { // 替换源信息为旧站点 request.origin = { custom: { domainName: 'my-domain-legacy.com', port: 443, protocol: 'https', readTimeout: 5, keepaliveTimeout: 5, customHeaders: {}, sslProtocols: ['TLSv1.2', 'TLSv1.1'], } }; // 修改Host头为旧域名,确保旧站点能正确处理请求 request.headers.host = [{ key: 'Host', value: 'my-domain-legacy.com' }]; // 保留原请求路径,无需修改uri } return callback(null, request); };
同时需确保Lambda@Edge函数部署在us-east-1区域,并拥有以下权限:
cloudfront:UpdateDistributionlambda:InvokeFunction- 允许关联到CloudFront分发的对应行为上
2. 改用支持外部重写的部署工具
如果不想编写Lambda函数,可以替换SST为以下工具:
- Vercel:原生支持Next.js的
rewrites配置,直接在next.config.js中添加外部重写规则:module.exports = { async rewrites() { return [ { source: '/company/:path*', destination: 'https://my-domain-legacy.com/company/:path*', }, ]; }, }; - Serverless Framework:通过配置CloudFront自定义源和行为,实现外部URL重写,灵活性更高
3. CloudFront直接配置行为规则
无需编写代码,直接在CloudFront分发中配置:
- 新增行为,路径模式设为
/company* - 将该行为的源设置为旧站点的自定义源(
my-domain-legacy.com) - 配置缓存策略,确保请求头(如Host)正确转发到旧站点
内容的提问来源于stack exchange,提问作者Michael Harley
相关产品推荐
相关产品推荐

