利用 Cloudflare Workers 为 Bento 创建自定义域名
脚本:
const BENTO_USERNAME = 'singee'
const BASE_URL = "https://singee.me"
export default {
async fetch(request, env, ctx) {
return handleRequest(request);
},
};
async function handleRequest(request) {
// Extracts the path from the request URL
const path = new URL(request.url).pathname;
// By default, the URL is set to 'https://bento.me'
// appended with the path
let url = 'https://bento.me' + path;
// If the path includes 'v1', the URL is changed to
// 'https://api.bento.me' appended with the path
if (path.includes('v1')) {
url = 'https://api.bento.me' + path;
}
// If the URL is 'https://bento.me/' the URL is changed to
// 'https://bento.me/' appended with the BENTO_USERNAME
if (url === 'https://bento.me/') {
url = 'https://bento.me/' + BENTO_USERNAME;
}
// Basic headers for the fetch request are defined
let headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,HEAD,POST,OPTIONS',
};
// The URL is fetched with the defined headers
const response = await fetch(url, { headers });
// The content type is extracted from the response headers
const contentType = response.headers.get('content-type');
// The response is parsed based on its content type
let results = await parseResponseByContentType(response, contentType);
// If the results are not an ArrayBuffer
// all calls to the bento API are replaced with our BASE_URL
// This is a workaround to fix CORS errors that occur otherwise
if (!(results instanceof ArrayBuffer)) {
results = results.replaceAll('https://api.bento.me', BASE_URL);
}
// The content type is added to the headers
headers['content-type'] = contentType;
// A new response is returned with the results and headers
return new Response(results, { headers });
}
async function parseResponseByContentType(response, contentType) {
// If there's no content type, the response is returned as text
if (!contentType) return await response.text();
// Depending on the content type, different actions are taken
switch (true) {
case contentType.includes('application/json'):
// If the content type is JSON, the response is returned as a JSON string
return JSON.stringify(await response.json());
case contentType.includes('text/html'):
const transformedResponse = new HTMLRewriter()
.on('body', {
element(element) {
element.append(
`
<style>
main>div.fixed {display: none}
</style>
`,
{ html: true },
);
},
})
.transform(response);
// The transformed response is returned as text
return await transformedResponse.text();
case contentType.includes('font'):
// If the content type is a font, the response is returned as an ArrayBuffer
return await response.arrayBuffer();
case contentType.includes('image'):
// If the content type is an image, the response is returned as an ArrayBuffer
return await response.arrayBuffer()
default:
// If the content type is anything else, the response is returned as text
return await response.text();
}
}
使用方式:创建新的 CF Workers 脚本,将以上脚本内容粘贴过去,修改最上面的 BENTO_USERNAME 为你的 bento 用户名、BASE_URL 为你要自定义域名的名称,保存部署后绑定自定义域名即可
参考:https://jayfranco.hashnode.dev/custom-domain-for-bento-with-cloudflare-workers
备注:该脚本利用 main>div.fixed {display: none}
隐藏了左下角的 Bento 标识,不是为了刻意隐瞒是用 Bento 做的,而是因为如果不隐藏左下角会是一个错误的 undefined 网址影响体验