找回密码
 注册
搜索
免费空间 免费域名 免费AI 老牌主机商首月仅1美分!27美元/年!Spaceship优惠码 Namecheap优惠码阿里云2核2G3M新老续费同享99元/年!
查看: 1222|回复: 10

[建站交流] 云函数版导航页-给D哥上上劲

[复制链接]
发表于 2024-3-7 11:59:42 | 显示全部楼层 |阅读模式
CF-Worker-Dir是一款适用于Cloudflare Worker平台上的云函数程序,可以使用它在一分钟内搭建属于自己的导航页。面。CF-Worker-Dir提供丰富的自定义配置,同时它还可以预留了接口帮助你售出自己域名。如果你的域名还没有搭建网站,不如先利用CF-Worker-Dir让你的域名不再浪费。




这款导航的亮点在于无服务端,轻量级云函数,并且无需服务器纯白嫖


甚至为我们留了卖域名的接口,让闲置正在售卖的mjj域名用起来,


另外一个好处是可以利用waf规则,利用防火墙来封禁或js质询某个地区的IP,已达到防范某些低级d哥的小把戏(虽然某些大鸡仔扛不住,但基本上卡拉米都能解决),我这设置了国外js质询,还不能完全禁海外IP,毕竟我基本上长期挂着富强!


当然如果说流量蛮大的话,建议还是做专业的防火墙策略!


下面就是他的worker代码,非常轻量级,就三百行的样子(不包括cssjs静态),就完成了一个导航站
  1. /**
  2. *  自定义网站配置
  3. */
  4. const config = {
  5.   title: "自定义导航",                 //write your website title
  6.   subtitle: "Cloudflare Workers Dir", //write your website subtitle
  7.   logo_icon: "sitemap",               //select your logo by semantic-ui icon (you can get more msg in:https://semantic-ui.com/elements/icon.html)
  8.   hitokoto: true,                     //use hitokoto or not
  9.   search:true,                        //enable search function
  10.   search_engine:[                     //choose search engine which you use
  11.     {
  12.       name:"百 度",
  13.       template:"https://www.baidu.com/s?wd=$s"
  14.     },
  15.     {
  16.       name:"谷 歌",
  17.       template:"https://www.google.com/search?q=$s"
  18.     },
  19.     {
  20.       name:"必 应",
  21.       template:"https://www.bing.com/search?q=$s"
  22.     },
  23.     {
  24.       name:"搜 狗",
  25.       template:"https://www.sogou.com/web?query=$s"
  26.     }
  27.   ],
  28.   selling_ads: true,                  //Selling your domain or not.(turning on may be helpful for selling this domain by showing some ads.)
  29.   sell_info:{
  30.     domain:"example.com",
  31.     price:500,                        //domain price
  32.     mon_unit:"yen sign",              //monetary unit
  33.     contact:[                         //how to contact you
  34.       {
  35.         type:"envelope",               //contact type ("weixin","qq","telegram plane","envelope" or "phone")
  36.         content:"info@example.com"
  37.       }
  38.     ]                        
  39.   },
  40.   lists: [                            //Url list
  41.     {
  42.       name:"技术",
  43.       icon:"code",
  44.       list:[
  45.         {
  46.           url:"https://oschina.net/",
  47.           name:"开源中国",
  48.           desc:"程序员集散地"
  49.         },
  50.         {
  51.           url:"https://v2ex.com",
  52.           name:"V2EX",
  53.           desc:"程序员集散地"
  54.         },
  55.         {
  56.           url:"https://csdn.net/",
  57.           name:"CSDN技术社区",
  58.           desc:"程序员集散地"
  59.         },
  60.         {
  61.           url:"https://github.com/",
  62.           name:"Github",
  63.           desc:"程序员集散地"
  64.         },
  65.       ]
  66.     },
  67.     {
  68.       name:"学习",
  69.       icon:"graduation cap",
  70.       list:[
  71.         {
  72.           url:"https://w3school.com.cn/",
  73.           name:"W3school在线教程",
  74.           desc:"程序员集散地"
  75.         },
  76.         {
  77.           url:"https://runoob.com/",
  78.           name:"菜鸟教程",
  79.           desc:"程序员集散地"
  80.         },
  81.         {
  82.           url:"https://segmentfault.com/",
  83.           name:"思否社区",
  84.           desc:"程序员集散地"
  85.         },
  86.         {
  87.           url:"https://jianshu.com/",
  88.           name:"简书",
  89.           desc:"程序员集散地"
  90.         },
  91.       ]
  92.     }
  93.   ]
  94. }
  95. const el = (tag, attrs, content) => `<${tag} ${attrs.join(" ")}>${content}</${tag}>`;

  96. async function handleRequest(request) {
  97.   const init = {
  98.     headers: {
  99.       'content-type': 'text/html;charset=UTF-8',
  100.     },
  101.   }
  102.   return new Response(renderHTML(renderIndex(),config.selling_ads? renderSeller() :null), init);
  103. }
  104. addEventListener('fetch', event => {
  105.   return event.respondWith(handleRequest(event.request))
  106. })

  107. /*通过分析链接 实时获取favicon
  108. * @url 需要分析的Url地址
  109. */
  110. function getFavicon(url){
  111.   if(url.match(/https{0,1}:\/\//)){
  112.     //return "https://ui-avatars.com/api/?bold=true&size=36&background=0D8ABC&color=fff&rounded=true&name=" + url.split('//')[1];
  113.     return "https://www.google.cn/s2/favicons?sz=64&domain_url=" + url;
  114.   }else{
  115.     //return "https://ui-avatars.com/api/?bold=true&size=36&background=0D8ABC&color=fff&rounded=true&name=" + url;
  116.     return "https://www.google.cn/s2/favicons?sz=64&domain_url=http://" + url;
  117.   }
  118. }

  119. /** Render Functions
  120. *  渲染模块函数
  121. */

  122. function renderIndex(){
  123.   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') + ' &copy; Base on ' + el('a',['class="ui label"'],el('i',['class="balance scale icon"'],"") + 'MIT License')));
  124.   return renderHeader() + renderMain() + footer;
  125. }

  126. function renderHeader(){
  127.   const item = (template,name) => el('a',['class="item"',`data-url="${template}"`],name);

  128.   var nav = el('div',['class="ui large secondary inverted menu"'],el('div',['class="item"'],el('p',['id="hitokoto"'],'条条大路通罗马')))
  129.   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)));
  130.   var menu = el('div',['id="sengine"','class="ui bottom attached tabular inverted secondary menu"'],el('div',['class="header item"'],'&nbsp;') + config.search_engine.map((link,key) =>{
  131.     if(key == 0){
  132.       return el('a',['class="active item"',`data-url="${link.template}"`],link.name);
  133.     }else{
  134.       return item(link.template,link.name);
  135.     }
  136.   }).join(""))
  137.   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"'],""));
  138.   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>' : ''}`)))
  139. }

  140. function renderMain() {
  141.   var main = config.lists.map((item) => {
  142.     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)));
  143.     const divider = el('h4',['class="ui horizontal divider header"'],el('i',[`class="${item.icon} icon"`],"")+item.name);

  144.     var content = el('div',['class="ui four stackable cards"'],item.list.map((link) =>{
  145.       return card(link.url,link.name,link.desc);
  146.     }).join(""));

  147.     return el('div',['class="ui basic segment"'],divider + content);
  148.   }).join("");
  149.   
  150.   return el('main',[],el('div',['class="ui container"'],main));
  151. }

  152. function renderSeller() {
  153.   const item = (type,content) => el('div',['class="item"'],el('i',[`class="${type} icon"`],"") + el('div',['class="content"'],content));
  154.   var title = el('h1',['class="ui yellow dividing header"'],el('i',['class="gem outline icon"'],"") + el('div',['class="content"'],config.sell_info.domain + ' 正在出售'));
  155.   var action = el('div',['class="actions"'],el('div',['class="ui basic cancel inverted button"'],el('i',['class="reply icon"'],"") + '返回'));

  156.   var contact = config.sell_info.contact.map((list) => {
  157.     return item(list.type,list.content);
  158.   }).join("");
  159.   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));
  160.   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)));
  161.   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))));

  162.   return el('div',['id="seller"','class="ui basic modal"'],title + content + action);
  163. }

  164. function renderHTML(index,seller) {
  165.   return `<!DOCTYPE html>
  166.   <html lang="en">
  167.   <head>
  168.       <meta charset="UTF-8">
  169.       <meta name="viewport" content="width=device-width, initial-scale=1.0">
  170.       <meta http-equiv="X-UA-Compatible" content="ie=edge">
  171.       <title>${config.title} - ${config.subtitle}</title>
  172.       <link href="https://cdn.jsdelivr.net/npm/semantic-ui-css@2.4.1/semantic.min.css" rel="stylesheet">
  173.       <link href="https://cdn.jsdelivr.net/gh/sleepwood/cf-worker-dir@0.1.1/style.css" rel="stylesheet">
  174.       <script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
  175.       <script src="https://cdn.jsdelivr.net/npm/semantic-ui-css@2.4.1/semantic.min.js"></script>
  176.   </head>
  177.   <body>
  178.     ${index}
  179.     ${config.selling_ads ? seller : ''}
  180.     <script src="https://v1.hitokoto.cn/?encode=js&select=%23hitokoto" defer></script>
  181.     <script>
  182.       $('#sengine a').on('click', function (e) {
  183.         $('#sengine a.active').toggleClass('active');
  184.         $(e.target).toggleClass('active');
  185.         $('#search-fav').attr('src',$(e.target).data('url').match(`+/https{0,1}:\/\/\S+\//+`)[0] + '/favicon.ico') ;
  186.       });
  187.       $('.search').on('click', function (e) {
  188.           var url = $('#sengine a.active').data('url');
  189.           url = url.replace(`+/\$s/+`,$('#searchinput').val());
  190.           window.open(url);
  191.       });
  192.       /* 鼠标聚焦时,回车事件 */
  193.       $("#searchinput").bind("keypress", function(){
  194.           if (event.keyCode == 13){
  195.           // 触发需要调用的方法
  196.           $(".search").click();
  197.           }
  198.       });
  199.       $('#menubtn').on('click', function (e) {
  200.           $('#seller').modal('show');
  201.       });
  202.     </script>
  203.   </body>

  204.   </html>`
  205. }
复制代码


下面是我的演示站以及效果图


演示站:发疯导航--[url]https://dh.966168.xyz/[/url]




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
发表于 2024-3-8 15:13:31 | 显示全部楼层
谢谢分享
发表于 2024-3-10 17:16:05 | 显示全部楼层
感谢分享
发表于 2024-3-10 17:43:32 | 显示全部楼层
确实不错
发表于 2024-3-10 17:46:11 | 显示全部楼层
静态页面图片怎么办,放在第三方?
发表于 2024-3-10 19:16:37 | 显示全部楼层
厉害了,纯html的导航站
 楼主| 发表于 2024-3-10 20:15:29 | 显示全部楼层
univzero 发表于 2024-3-10 19:16
厉害了,纯html的导航站

准确的说连HTML都不算,就是一个云函数
 楼主| 发表于 2024-3-10 20:17:12 | 显示全部楼层
jason 发表于 2024-3-10 17:46
静态页面图片怎么办,放在第三方?

你说的是ico吗,谷歌api自动获取
发表于 2024-3-10 20:35:31 | 显示全部楼层
sterling 发表于 2024-3-10 20:17
你说的是ico吗,谷歌api自动获取
加个logo呢
发表于 2024-3-10 21:43:49 来自手机 | 显示全部楼层
学习学习,感谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|小黑屋|免费吧论坛

GMT+8, 2024-11-22 07:07 , Processed in 0.023990 second(s), 3 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表