在尝试了很多不同的代码之后,我终于想出了一个 Lambda 边缘表达式,它同时解决了两个问题:
- 需要
.html
在URL末尾插入
- NextJS 动态路由在刷新或直接访问 URL 时不起作用。
下面的代码基本上首先处理动态路由。它使用正则表达式来理解当前 URL 并将请求重定向到正确的[id].html
文件。之后,如果没有一个正则表达式匹配,并且 URL 不包含.html
扩展名,它会添加扩展名并检索正确的文件。
const config = {
suffix: '.html',
appendToDirs: 'index.html',
removeTrailingSlash: false,
};
const regexSuffixless = /\/[^/.]+$/; // e.g. "/some/page" but not "/", "/some/" or "/some.jpg"
const regexTrailingSlash = /.+\/$/; // e.g. "/some/" or "/some/page/" but not root "/"
const dynamicRouteRegex = /\/subpath\/\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/; // e.g /urs/some-uuid; // e.g. '/subpath/uuid'
exports.handler = function handler(event, context, callback) {
const { request } = event.Records[0].cf;
const { uri } = request;
const { suffix, appendToDirs, removeTrailingSlash } = config;
//Checks for dynamic route and retrieves the proper [id].html file
if (uri.match(dynamicRouteRegex)) {
request.uri = "/subpath/[id].html";
callback(null, request);
return;
}
// Append ".html" to origin request
if (suffix && uri.match(regexSuffixless)) {
request.uri = uri + suffix;
callback(null, request);
return;
}
// Append "index.html" to origin request
if (appendToDirs && uri.match(regexTrailingSlash)) {
request.uri = uri + appendToDirs;
callback(null, request);
return;
}
// Redirect (301) non-root requests ending in "/" to URI without trailing slash
if (removeTrailingSlash && uri.match(/.+\/$/)) {
const response = {
// body: '',
// bodyEncoding: 'text',
headers: {
'location': [{
key: 'Location',
value: uri.slice(0, -1)
}]
},
status: '301',
statusDescription: 'Moved Permanently'
};
callback(null, response);
return;
}
// If nothing matches, return request unchanged
callback(null, request);
};
非常感谢@LongZheng 的回答。出于某种原因,他的代码对我不起作用,但可能对某些人有用,所以请查看他的答案。另外,对这个lambda-edge-nice-urls repo的创建者 Manc 大喊一声。我的代码基本上是两者的混合。