password
type
Post
status
Published
date
Aug 21, 2021
slug
summary
Cloudflare Workers
tags
cloudflare
category
技术分享
icon
CF-Worker-Dir是一款适用于Cloudflare Worker平台上的云函数程序,可以使用它在一分钟内搭建属于自己的导航页面。CF-Worker-Dir提供丰富的自定义配置,同时它还可以预留了接口帮助你售出自己域名。如果你的域名还没有搭建网站,不如先利用CF-Worker-Dir让你的域名不再浪费。
在绑定域名之后,选择Workers

选择Manage Workers

选择Create a Worker
在右侧能看到每天100000次的请求数量

选择{}Quick edit,进行编辑

将CF-Worker-Dir里的index.js复制粘贴至对应的config{},并修改成自己的信息
最后点击保存并发布。

你就拥有了属于自己的导航页。

ps:原作者还在持续更新!
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) /** * Respond to the request * @param {Request} request */ async function handleRequest(request) { return new Response('hello world', {status: 200}) } /** * 自定义网站配置 */ const config = { title: "三生万物", //write your website title subtitle: "道生一,一生二,二生三", //write your website subtitle logo_icon: "sitemap", //select your logo by semantic-ui icon (you can get more msg in:https://semantic-ui.com/elements/icon.html) hitokoto: true, //use hitokoto or not search:true, //enable search function search_engine:[ //choose search engine which you use { name:"必 应", template:"https://cn.bing.com/search?q=$s" }, { name:"YANDEX", template:"https://yandex.com/search/?text=$s" }, { name:"谷 歌", template:"https://www.google.com/search?q=$s" }, { name:"百 度", template:"https://www.baidu.com/s?wd=$s" }, ], selling_ads: false, //Selling your domain or not.(turning on may be helpful for selling this domain by showing some ads.) sell_info:{ domain:"011223.xyz", price:1000, //domain price mon_unit:"yen sign", //monetary unit contact:[ { type:"phone", content:"+" },//how to contact you { type:"envelope", //contact type ("weixin","qq","telegram plane","envelope" or "phone") content:"gmail.com" } ] }, lists: [ //Url list { name:"技术", icon:"code", list:[ { url:"https://wiki.011223.xyz", name:"7秒记忆", desc:"GITHUB站点" }, { url:"https://zhong.011223.xyz", name:"东皇钟", desc:"NOTION" }, { url:"https://xyz.011223.xyz/", name:"知识库", desc:"主站" }, { url:"https://notion.011223.xyz", name:"知识库", desc:"备用" }, { url:"https://musicforprogramming.net/", name:"背景音乐", desc:"适合程序员的背景音乐" }, ] }, { name:"博客", icon:"BLOG", list:[ { url:"https://wzyboy.im", name:"wzyboy", desc:"wzyboy" }, { url:"https://blog.naaln.com", name:"Whyliam", desc:"人生若如初見" }, { url:"https://ednovas.xyz", name:"ednovas", desc:"ednovas" }, { url:"https://www.hongweipeng.com/", name:"栖迟於一丘", desc:"栖迟於一丘" }, { url:"https://gine.me/", name:"Mayne", desc:"Notion/Gatsby/Netlify" }, { url:"https://xiaolincoding.com", name:"小林", desc:"小林coding" }, { url:"https://iao.su", name:"不死鸟", desc:"分享为王" }, ] }, { name:"图库", icon:"graduation cap", list:[ { url:"https://www.backblaze.com", name:"B2", desc:"自建图库" }, { url:"https://imgchr.com", name:"路过图库", desc:"永不收费" }, { url:"https://sm.ms", name:"SM.MS", desc:"图库" }, { url:"https://www.instapaper.com/", name:"instapaper", desc:"FEED" }, { url:"https://portal.qiniu.com/signup?type=1", name:"qiniu", desc:"oss" }, { url:"https://unsplash.com/login", name:"unsplash", desc:"unsplash" }, { url:"http://www.52pojie.cn", name:"52pojie", desc:"52pojie" }, ] }, { name:"社区", icon:"graduation cap", list:[ { url:"https://www.msdmanuals.cn", name:"MSD诊疗手册", desc:"MSD诊疗手册" }, { url:"http://upwith.me/", name:"永澄老师", desc:"个人成长目标" }, { url:"https://www.phodal.com/", name:"Phodal", desc:"狼和凤凰" }, { url:"https://www.eslbuzz.com/", name:"1000+英语课程", desc:"FREE" }, { url:"https://segmentfault.com/", name:"思否社区", desc:"程序员集散地" }, { url:"https://jianshu.com/", name:"简书", desc:"程序员集散地" }, { url:"https://w3school.com.cn/", name:"W3school在线教程", desc:"程序员集散地" }, { url:"https://www.fakenamegenerator.com", name:"神奇的社工网站", desc:"自动身份" }, { url:"https://www.csdn.net", name:"csdn", desc:"csdn" }, { url:"http://www.51cto.com", name:"51CTO", desc:"51CTO" }, { url:"https://www.ituring.com.cn", name:"图灵社区", desc:"图灵社区" }, { url:"http://guanjianfeng.com/", name:"老管网络日志", desc:"虚拟化" }, { url:"https://www.c82.net/werner/#preface", name:"配色", desc:"配色" }, { url:"https://jianshu.com/", name:"简书", desc:"程序员集散地" }, ] }, { name:"七色花", icon:"graduation cap", list:[ { url:"https://ddrk.me/", name:"低端影视", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.qianoo.cn/", name:"厂长资源", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.libvio.me/", name:"Libvio", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.ysgc.cc/", name:"影视工厂", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.zxzj.fun", name:"在线之家", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"http://www.lezhutv.com", name:"乐猪TV", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://auete.com", name:"Auete", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://cokemv.me/", name:"Cokemv", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.o8tv.com/", name:"555电影", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" },//https://www.555dy.fun/ { url:"https://dmys1.com/", name:"大米星球", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.hdmoli.com/", name:"HDmoli", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"http://bukaivip1.com/", name:"不开VIP", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.duboku.net", name:"独播库", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://app.movie", name:"APP", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://www.adcmove.com", name:"ADC电影网", desc:"支持正版人人有责,日常观看请使用正版软件,仅作搜索用" }, { url:"https://epg.112114.xyz/", name:"直播电子节目单", desc:"EPG配合IPTV使用,效果更佳" }, { url:"https://www.tvcha.cn/", name:"TVCHA", desc:"EPG配合IPTV使用,效果更佳" }, { url:"http://www.tv.cn/", name:"TVCN", desc:"EPG配合IPTV使用,效果更佳" }, { url:"https://www.tvmao.com/", name:"电视猫", desc:"EPG配合IPTV使用,效果更佳" }, { url:"https://SQ688.Com", name:"无损音乐", desc:"支持正版人人有责,仅作搜索之用" }, { url:"http://www.yinfans.me/", name:"音范丝", desc:" " }, { url:"http://api.ckzy.vip", name:"超快资源", desc:"利用API解析" }, { url:"http://www.meiriyixue.cn/jx/", name:"每日一学", desc:"含解析和直播" }, { url:"http://home.jundie.top:81/TVBox/yosakoi.json", name:"解析合集", desc:"Box配置表" }, { url:"https://notabug.org/GY1111", name:"合集", desc:"TV菜单" }, { url:"https://github.com/Kimentanm", name:"APTV作者", desc:"GITHUB" }, { url:"http://lcoc.top/vip2.3/", name:"蓝调", desc:"智能解析" }, { url:"https://www.ikukk.com/?url=", name:"爱酷解析", desc:"" }, ] }, { name:"BT", icon:"graduation cap", list:[ { url:"https://thepiratebay.org/", name:"free-api", desc:"收集免费的接口服务" }, { url:"http://torrentz.eu/", name:"lightink-小说API", desc:"阅读书源在线解析api接口" }, { url:"http://www.sumotorrent.com/", name:"free-api", desc:"收集免费的接口服务" }, { url:"http://bitsnoop.com/", name:"lightink-小说API", desc:"阅读书源在线解析api接口" }, { url:" http://katcr.to/", name:"free-api", desc:"收集免费的接口服务" }, { url:"http://www.eztv.it", name:"lightink-小说API", desc:"阅读书源在线解析api接口" }, ] }, { name:"API", icon:"graduation cap", list:[ { url:"https://github.com/fangzesheng/free-api", name:"free-api", desc:"收集免费的接口服务" }, { url:"https://github.com/lightink-qingmo/lightink-server", name:"lightink-小说API", desc:"阅读书源在线解析api接口" } ] } ] } const el = (tag, attrs, content) => `<${tag} ${attrs.join(" ")}>${content}</${tag}>`; async function handleRequest(request) { const init = { headers: { 'content-type': 'text/html;charset=UTF-8', }, } return new Response(renderHTML(renderIndex(),config.selling_ads? renderSeller() :null), init); } addEventListener('fetch', event => { return event.respondWith(handleRequest(event.request)) }) /*通过分析链接 实时获取favicon * @url 需要分析的Url地址 */ function getFavicon(url){ if(url.match(/https{0,1}:\/\//)){ //return "https://ui-avatars.com/api/?bold=true&size=36&background=0D8ABC&color=fff&rounded=true&name=" + url.split('//')[1]; return "https://icon.occ.hk/get.php?url=" + url; }else{ //return "https://ui-avatars.com/api/?bold=true&size=36&background=0D8ABC&color=fff&rounded=true&name=" + url; return "https://icon.occ.hk/get.php?url=http://" + url; } } /** Render Functions * 渲染模块函数 */ function renderIndex(){ const footer = el('footer',[],el('div',['class="footer"'],'Powered by' + el('a',['class="ui label"','href="https://github.com/sleepwood/cf-worker-dir"','target="_blank"'],el('i',['class="github icon"'],"") + 'Cf-Worker-Dir') + ' © Base on ' + el('a',['class="ui label"'],el('i',['class="balance scale icon"'],"") + 'MIT License'))); return renderHeader() + renderMain() + footer; } function renderHeader(){ const item = (template,name) => el('a',['class="item"',`data-url="${template}"`],name); var nav = el('div',['class="ui large secondary inverted menu"'],el('div',['class="item"'],el('p',['id="hitokoto"'],'条条大路通罗马'))) var title = el('h1',['class="ui inverted header"'],el('i',[`class="${config.logo_icon} icon"`],"") + el('div',['class="content"'],config.title + el('div',['class="sub header"'],config.subtitle))); var menu = el('div',['id="sengine"','class="ui bottom attached tabular inverted secondary menu"'],el('div',['class="header item"'],' ') + config.search_engine.map((link,key) =>{ if(key == 0){ return el('a',['class="active item"',`data-url="${link.template}"`],link.name); }else{ return item(link.template,link.name); } }).join("")) var input = el('div',['class="ui left corner labeled right icon fluid large input"'],el('div',['class="ui left corner label"'],el('img',['id="search-fav"','class="left floated avatar ui image"','src="https://www.baidu.com/favicon.ico"'],"")) + el('input',['id="searchinput"','type="search"','placeholder="搜索你想要知道的……"','autocomplete="off"'],"") + el('i',['class="inverted circular search link icon"'],"")); return el('header',[],el('div',['id="head"','class="ui inverted vertical masthead center aligned segment"'],(config.hitokoto ? el('div',['id="nav"','class="ui container"'],nav) : "") + el('div',['id="title"','class="ui text container"'],title + (config.search ? input + menu :"") + `${config.selling_ads ? '<div><a id="menubtn" class="red ui icon inverted button"><i class="heart icon"></i> 喜欢此域名 </a></div>' : ''}`))) } function renderMain() { var main = config.lists.map((item) => { const card = (url,name,desc)=> el('a',['class="card"',`href=${url}`,'target="_blank"'],el('div',['class="content"'],el('img',['class="left floated avatar ui image"',`src=${getFavicon(url)}`],"") + el('div',['class="header"'],name) + el('div',['class="meta"'],desc))); const divider = el('h4',['class="ui horizontal divider header"'],el('i',[`class="${item.icon} icon"`],"")+item.name); var content = el('div',['class="ui four stackable cards"'],item.list.map((link) =>{ return card(link.url,link.name,link.desc); }).join("")); return el('div',['class="ui basic segment"'],divider + content); }).join(""); return el('main',[],el('div',['class="ui container"'],main)); } function renderSeller() { const item = (type,content) => el('div',['class="item"'],el('i',[`class="${type} icon"`],"") + el('div',['class="content"'],content)); var title = el('h1',['class="ui yellow dividing header"'],el('i',['class="gem outline icon"'],"") + el('div',['class="content"'],config.sell_info.domain + ' 正在出售')); var action = el('div',['class="actions"'],el('div',['class="ui basic cancel inverted button"'],el('i',['class="reply icon"'],"") + '返回')); var contact = config.sell_info.contact.map((list) => { return item(list.type,list.content); }).join(""); var column = el('div',['class="column"'],el('h3',['class="ui center aligned icon inverted header"'],el('i',['class="circular envelope open outline grey inverted icon"'],"") + '联系我') + el('div',['class="ui relaxed celled large list"'],contact)); var price = el('div',['class="column"'],el('div',['class="ui large yellow statistic"'],el('div',['class="value"'],el('i',[`class="${config.sell_info.mon_unit} icon"`],"") + config.sell_info.price))); var content = el('div',['class="content"'],el('div',['class="ui basic segment"'],el('div',['class="ui two column stackable center aligned grid"'],el('div',['class="ui inverted vertical divider"'],'感兴趣?') + el('div',['class="middle aligned row"'],price + column)))); return el('div',['id="seller"','class="ui basic modal"'],title + content + action); } function renderHTML(index,seller) { return `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>${config.title} - ${config.subtitle}</title> <link href="https://cdn.jsdelivr.net/npm/semantic-ui-css@2.4.1/semantic.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/gh/sleepwood/cf-worker-dir@0.1.1/style.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/semantic-ui-css@2.4.1/semantic.min.js"></script> </head> <body> ${index} ${config.selling_ads ? seller : ''} <script src="https://v1.hitokoto.cn/?encode=js&select=%23hitokoto" defer></script> <script> $('#sengine a').on('click', function (e) { $('#sengine a.active').toggleClass('active'); $(e.target).toggleClass('active'); $('#search-fav').attr('src',$(e.target).data('url').match(`+/https{0,1}:\/\/\S+\//+`)[0] + '/favicon.ico') ; }); $('.search').on('click', function (e) { var url = $('#sengine a.active').data('url'); url = url.replace(`+/\$s/+`,$('#searchinput').val()); window.open(url); }); /* 鼠标聚焦时,回车事件 */ $("#searchinput").bind("keypress", function(){ if (event.keyCode == 13){ // 触发需要调用的方法 $(".search").click(); } }); $('#menubtn').on('click', function (e) { $('#seller').modal('show'); }); </script> </body> </html>` }
/** * For OneDrive * IS_CN: 如果为世纪互联版本,请将 0 改为 1 * EXPOSE_PATH:暴露路径,如全盘展示请留空,否则按 '/媒体/音乐' 的格式填写 * ONEDRIVE_REFRESHTOKEN: refresh_token */ const IS_CN = 0; const EXPOSE_PATH = "" const ONEDRIVE_REFRESHTOKEN = "" async function handleRequest(request) { let requestPath let querySplited let queryString = request.url.split('?')[1] if (queryString) { querySplited = queryString.split('=') } if (querySplited && querySplited[0] === 'file') { const file = querySplited[1] const fileName = file.split('/').pop(); requestPath = file.replace('/' + fileName, '') const url = await fetchFiles(requestPath, fileName) return Response.redirect(url, 302) } else { const { headers } = request const contentType = headers.get('content-type') let body={} if (contentType && contentType.includes('form')) { const formData = await request.formData() for (let entry of formData.entries()) { body[entry[0]] = entry[1] } } requestPath = body ? body['?path'] : ''; const files = await fetchFiles(requestPath, null, body.passwd); return new Response(files, { headers: { 'content-type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin': '*' } }) } } addEventListener('fetch', event => { return event.respondWith(handleRequest(event.request)) }) const clientId = [ '4da3e7f2-bf6d-467c-aaf0-578078f0bf7c', '04c3ca0b-8d07-4773-85ad-98b037d25631' ] const clientSecret = [ '7/+ykq2xkfx:.DWjacuIRojIaaWL0QI6', 'h8@B7kFVOmj0+8HKBWeNTgl@pU/z4yLB' ] const oauthHost = [ 'https://login.microsoftonline.com', 'https://login.partner.microsoftonline.cn' ] const apiHost = [ 'https://graph.microsoft.com', 'https://microsoftgraph.chinacloudapi.cn' ] const OAUTH = { 'redirectUri': 'https://scfonedrive.github.io', 'refreshToken': ONEDRIVE_REFRESHTOKEN, 'clientId': clientId[IS_CN], 'clientSecret': clientSecret[IS_CN], 'oauthUrl': oauthHost[IS_CN] + '/common/oauth2/v2.0/', 'apiUrl': apiHost[IS_CN] + '/v1.0/me/drive/root', 'scope': apiHost[IS_CN] + '/Files.ReadWrite.All offline_access' } async function gatherResponse(response) { const { headers } = response const contentType = headers.get('content-type') if (contentType.includes('application/json')) { return await response.json() } else if (contentType.includes('application/text')) { return await response.text() } else if (contentType.includes('text/html')) { return await response.text() } else { return await response.text() } } async function getContent(url) { const response = await fetch(url) const result = await gatherResponse(response) return result } async function getContentWithHeaders(url, headers) { const response = await fetch(url, { headers: headers }) const result = await gatherResponse(response) return result } async function fetchFormData(url, data) { const formdata = new FormData(); for (const key in data) { if (data.hasOwnProperty(key)) { formdata.append(key, data[key]) } } const requestOptions = { method: 'POST', body: formdata }; const response = await fetch(url, requestOptions) const result = await gatherResponse(response) return result } async function fetchAccessToken() { url = OAUTH['oauthUrl'] + 'token' data = { 'client_id': OAUTH['clientId'], 'client_secret': OAUTH['clientSecret'], 'grant_type': 'refresh_token', 'requested_token_use': 'on_behalf_of', 'refresh_token': OAUTH['refreshToken'] } const result = await fetchFormData(url, data) return result.access_token } async function fetchFiles(path, fileName, passwd) { if (!path || path === '/') { if (EXPOSE_PATH === '') { path = '' } else { path = ':' + EXPOSE_PATH } } else { if (EXPOSE_PATH === '') { path = ':' + path } else { path = ':' + EXPOSE_PATH + path } } const accessToken = await fetchAccessToken() const uri = OAUTH.apiUrl + encodeURI(path) + '?expand=children(select=name,size,parentReference,lastModifiedDateTime,@microsoft.graph.downloadUrl)' const body = await getContentWithHeaders(uri, { Authorization: 'Bearer ' + accessToken }) if (fileName) { let thisFile = null body.children.forEach(file => { if (file.name === decodeURIComponent(fileName)) { thisFile = file['@microsoft.graph.downloadUrl'] return } }) return thisFile } else { let files = [] let encrypted = false for (let i = 0; i < body.children.length; i++) { const file = body.children[i] if (file.name === '.password') { const PASSWD = await getContent(file['@microsoft.graph.downloadUrl']) if (PASSWD !== passwd) { encrypted = true; break } else { continue } } files.push({ name: file.name, size: file.size, time: file.lastModifiedDateTime, url: file['@microsoft.graph.downloadUrl'] }) } let parent if (body.children.length) { parent = body.children[0].parentReference.path } else { parent = body.parentReference.path } parent = parent.split(':').pop().replace(EXPOSE_PATH, '') || '/' parent = decodeURIComponent(parent) if (encrypted) { return JSON.stringify({ parent: parent, files: [], encrypted: true }) } else { return JSON.stringify({ parent: parent, files: files }) } } }
/* *For NotionBlog */ const MY_DOMAIN = "" const START_PAGE = "https://www.notion.so/{'公开的路径'}" addEventListener('fetch', event => { event.respondWith(fetchAndApply(event.request)) }) const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, HEAD, POST,PUT, OPTIONS", "Access-Control-Allow-Headers": "Content-Type", } function handleOptions(request) { if (request.headers.get("Origin") !== null && request.headers.get("Access-Control-Request-Method") !== null && request.headers.get("Access-Control-Request-Headers") !== null) { // Handle CORS pre-flight request. return new Response(null, { headers: corsHeaders }) } else { // Handle standard OPTIONS request. return new Response(null, { headers: { "Allow": "GET, HEAD, POST, PUT, OPTIONS", } }) } } async function fetchAndApply(request) { if (request.method === "OPTIONS") { return handleOptions(request) } let url = new URL(request.url) let response if (url.pathname.startsWith("/app") && url.pathname.endsWith("js")) { response = await fetch(`https://www.notion.so${url.pathname}`) let body = await response.text() try { response = new Response(body.replace(/www.notion.so/g, MY_DOMAIN).replace(/notion.so/g, MY_DOMAIN), response) // response = new Response(response.body, response) response.headers.set('Content-Type', "application/x-javascript") console.log("get rewrite app.js") } catch (err) { console.log(err) } } else if ((url.pathname.startsWith("/api"))) { response = await fetch(`https://www.notion.so${url.pathname}`, { body: request.body, // must match 'Content-Type' header headers: { 'content-type': 'application/json;charset=UTF-8', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36' }, method: "POST", // *GET, POST, PUT, DELETE, etc. }) response = new Response(response.body, response) response.headers.set('Access-Control-Allow-Origin', "*") } else if (url.pathname === `/`) { let pageUrlList = START_PAGE.split("/") let redrictUrl = `https://${MY_DOMAIN}/${pageUrlList[pageUrlList.length-1]}` return Response.redirect(redrictUrl, 301) } else { response = await fetch(`https://www.notion.so${url.pathname}`, { body: request.body, // must match 'Content-Type' header headers: request.headers, method: request.method, // *GET, POST, PUT, DELETE, etc. }) } return response }
