使用Cloudflare和notion搭建自己的博客

2023-10-27

欢迎访问我的个人博客ximikang.icu

使用Cloudflare和notion搭建自己的博客

使用过Nation的小伙伴一定在某个时刻冒出过这样子的想法:这个笔记应用这么好用,而且是基于Web端开发的,那为什么不可以用他来作为我自己的博客呢?这样我是不是可以用记笔记的方式来快速的实现和维护自己的博客了呢?

我搭建的个人博客,欢迎大家访问。https://notion.ximikang.icu/

Untitled

购买一个域名并将域名转移到Cloudflare

首先我们需要将域名的域名服务器设置为 Cloudflare 的域名服务器,这样就可以使用 Cloudflare 的 DNS 服务了。

注册Cloudflare ,然后在这里添加自己的域名:

Untitled

将你的域名指向notion

切换到 dns 页面,添加一条 CNAME 记录,如果你自己的二级域名为 blog.xxx.com,那么名称那就填 blog,目标填 Notion 的域名,保存。

Untitled

Untitled

或者需要将主域名设置为则为

Untitled

注意需要将代理状态切换至已代理,这样才能用cloudflare的免费CDN。

添加后下方就会显示已添加的域名,点击已添加的域名进入设置页面。

配置Cloudflare的Web Worker

配置workder使得我们访问我们上面定义的http请求可以自动改写。

Untitled

  1. 首先**管理Workers,**新建一个对应的notion的worker。

    Untitled

    获取notion页面中的链接ID,如图中的id需要在worker配置中使用。

    Untitled

    创建worker后编辑worker,将如下代码复制到worker中。

    /* CONFIGURATION STARTS HERE */
      
      /* 添加域名 notion.ximikang.icu*/
    
      const MY_DOMAIN = '';
      
      /*
    		添加刚才的id
    		例如:
    		'': 'bb1678c7e8fe47b29bf49aac08aebbb',
       */
      const SLUG_TO_PAGE = {
        '': '',
      };
      
      /* 添加主页面的标题和描述  */
      const PAGE_TITLE = '';
      const PAGE_DESCRIPTION = '';
      
      /* 可以选择显示的字体 https://fonts.google.com 
    	例如:const GOOGLE_FONT = 'Noto Sans Simplified Chinese';*/
      const GOOGLE_FONT = '';
      
      /* 添加自定义脚本,可以添加Google Analytics */
      const CUSTOM_SCRIPT = ``;
      
      /* CONFIGURATION ENDS HERE */
      
      const PAGE_TO_SLUG = {};
      const slugs = [];
      const pages = [];
      Object.keys(SLUG_TO_PAGE).forEach(slug => {
        const page = SLUG_TO_PAGE[slug];
        slugs.push(slug);
        pages.push(page);
        PAGE_TO_SLUG[page] = slug;
      });
      
      addEventListener('fetch', event => {
        event.respondWith(fetchAndApply(event.request));
      });
    
      function generateSitemap() {
        let sitemap = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
        slugs.forEach(
          (slug) =>
            (sitemap +=
              '<url><loc>https://' + MY_DOMAIN + '/' + slug + '</loc></url>')
        );
        sitemap += '</urlset>';
        return sitemap;
      }
      
      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);
        url.hostname = 'www.notion.so';
        if (url.pathname === '/robots.txt') {
          return new Response('Sitemap: https://' + MY_DOMAIN + '/sitemap.xml');
        }
        if (url.pathname === '/sitemap.xml') {
          let response = new Response(generateSitemap());
          response.headers.set('content-type', 'application/xml');
          return response;
        }
        let response;
        if (url.pathname.startsWith('/app') && url.pathname.endsWith('js')) {
          response = await fetch(url.toString());
          let body = await response.text();
          response = new Response(body.replace(/www.notion.so/g, MY_DOMAIN).replace(/notion.so/g, MY_DOMAIN), response);
          response.headers.set('Content-Type', 'application/x-javascript');
          return response;
        } else if ((url.pathname.startsWith('/api'))) {
          // Forward API
          response = await fetch(url.toString(), {
            body: url.pathname.startsWith('/api/v3/getPublicPageData') ? null : request.body,
            headers: {
              'content-type': 'application/json;charset=UTF-8',
              'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
            },
            method: 'POST',
          });
          response = new Response(response.body, response);
          response.headers.set('Access-Control-Allow-Origin', '*');
          return response;
        } else if (slugs.indexOf(url.pathname.slice(1)) > -1) {
          const pageId = SLUG_TO_PAGE[url.pathname.slice(1)];
          return Response.redirect('https://' + MY_DOMAIN + '/' + pageId, 301);
        } else {
          response = await fetch(url.toString(), {
            body: request.body,
            headers: request.headers,
            method: request.method,
          });
          response = new Response(response.body, response);
          response.headers.delete('Content-Security-Policy');
          response.headers.delete('X-Content-Security-Policy');
        }
      
        return appendJavascript(response, SLUG_TO_PAGE);
      }
      
      class MetaRewriter {
        element(element) {
          if (PAGE_TITLE !== '') {
            if (element.getAttribute('property') === 'og:title'
              || element.getAttribute('name') === 'twitter:title') {
              element.setAttribute('content', PAGE_TITLE);
            }
            if (element.tagName === 'title') {
              element.setInnerContent(PAGE_TITLE);
            }
          }
          if (PAGE_DESCRIPTION !== '') {
            if (element.getAttribute('name') === 'description'
              || element.getAttribute('property') === 'og:description'
              || element.getAttribute('name') === 'twitter:description') {
              element.setAttribute('content', PAGE_DESCRIPTION);
            }
          }
          if (element.getAttribute('property') === 'og:url'
            || element.getAttribute('name') === 'twitter:url') {
            element.setAttribute('content', MY_DOMAIN);
          }
          if (element.getAttribute('name') === 'apple-itunes-app') {
            element.remove();
          }
        }
      }
      
      class HeadRewriter {
        element(element) {
          if (GOOGLE_FONT !== '') {
            element.append(`<link href="https://fonts.googleapis.com/css?family=${GOOGLE_FONT.replace(' ', '+')}:Regular,Bold,Italic&display=swap" rel="stylesheet">
            <style>* { font-family: "${GOOGLE_FONT}" !important; }</style>`, {
              html: true
            });
          }
          element.append(`<style>
          div.notion-topbar > div > div:nth-child(3) { display: none !important; }
          div.notion-topbar > div > div:nth-child(4) { display: none !important; }
          div.notion-topbar > div > div:nth-child(5) { display: none !important; }
          div.notion-topbar > div > div:nth-child(6) { display: none !important; }
          div.notion-topbar-mobile > div:nth-child(3) { display: none !important; }
          div.notion-topbar-mobile > div:nth-child(4) { display: none !important; }
          div.notion-topbar > div > div:nth-child(1n).toggle-mode { display: block !important; }
          div.notion-topbar-mobile > div:nth-child(1n).toggle-mode { display: block !important; }
          </style>`, {
            html: true
          })
        }
      }
      
      class BodyRewriter {
        constructor(SLUG_TO_PAGE) {
          this.SLUG_TO_PAGE = SLUG_TO_PAGE;
        }
        element(element) {
          element.append(`<div style="display:none">Powered by <a href="http://fruitionsite.com">Fruition</a></div>
          <script>
          window.CONFIG.domainBaseUrl = 'https://${MY_DOMAIN}';
          const SLUG_TO_PAGE = ${JSON.stringify(this.SLUG_TO_PAGE)};
          const PAGE_TO_SLUG = {};
          const slugs = [];
          const pages = [];
          const el = document.createElement('div');
          let redirected = false;
          Object.keys(SLUG_TO_PAGE).forEach(slug => {
            const page = SLUG_TO_PAGE[slug];
            slugs.push(slug);
            pages.push(page);
            PAGE_TO_SLUG[page] = slug;
          });
          function getPage() {
            return location.pathname.slice(-32);
          }
          function getSlug() {
            return location.pathname.slice(1);
          }
          function updateSlug() {
            const slug = PAGE_TO_SLUG[getPage()];
            if (slug != null) {
              history.replaceState(history.state, '', '/' + slug);
            }
          }
          function onDark() {
            el.innerHTML = '<div title="Change to Light Mode" style="margin-left: auto; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgb(46, 170, 220); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px);"></div></div></div></div>';
            document.body.classList.add('dark');
            __console.environment.ThemeStore.setState({ mode: 'dark' });
          };
          function onLight() {
            el.innerHTML = '<div title="Change to Dark Mode" style="margin-left: auto; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgba(135, 131, 120, 0.3); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px);"></div></div></div></div>';
            document.body.classList.remove('dark');
            __console.environment.ThemeStore.setState({ mode: 'light' });
          }
          function toggle() {
            if (document.body.classList.contains('dark')) {
              onLight();
            } else {
              onDark();
            }
          }
          function addDarkModeButton(device) {
            const nav = device === 'web' ? document.querySelector('.notion-topbar').firstChild : document.querySelector('.notion-topbar-mobile');
            el.className = 'toggle-mode';
            el.addEventListener('click', toggle);
            nav.appendChild(el);
            onLight();
          }
          const observer = new MutationObserver(function() {
            if (redirected) return;
            const nav = document.querySelector('.notion-topbar');
            const mobileNav = document.querySelector('.notion-topbar-mobile');
            if (nav && nav.firstChild && nav.firstChild.firstChild
              || mobileNav && mobileNav.firstChild) {
              redirected = true;
              updateSlug();
              addDarkModeButton(nav ? 'web' : 'mobile');
              const onpopstate = window.onpopstate;
              window.onpopstate = function() {
                if (slugs.includes(getSlug())) {
                  const page = SLUG_TO_PAGE[getSlug()];
                  if (page) {
                    history.replaceState(history.state, 'bypass', '/' + page);
                  }
                }
                onpopstate.apply(this, [].slice.call(arguments));
                updateSlug();
              };
            }
          });
          observer.observe(document.querySelector('#notion-app'), {
            childList: true,
            subtree: true,
          });
          const replaceState = window.history.replaceState;
          window.history.replaceState = function(state) {
            if (arguments[1] !== 'bypass' && slugs.includes(getSlug())) return;
            return replaceState.apply(window.history, arguments);
          };
          const pushState = window.history.pushState;
          window.history.pushState = function(state) {
            const dest = new URL(location.protocol + location.host + arguments[2]);
            const id = dest.pathname.slice(-32);
            if (pages.includes(id)) {
              arguments[2] = '/' + PAGE_TO_SLUG[id];
            }
            return pushState.apply(window.history, arguments);
          };
          const open = window.XMLHttpRequest.prototype.open;
          window.XMLHttpRequest.prototype.open = function() {
            arguments[1] = arguments[1].replace('${MY_DOMAIN}', 'www.notion.so');
            return open.apply(this, [].slice.call(arguments));
          };
        </script>${CUSTOM_SCRIPT}`, {
            html: true
          });
        }
      }
      
      async function appendJavascript(res, SLUG_TO_PAGE) {
        return new HTMLRewriter()
          .on('title', new MetaRewriter())
          .on('meta', new MetaRewriter())
          .on('head', new HeadRewriter())
          .on('body', new BodyRewriter(SLUG_TO_PAGE))
          .transform(res);
      }
    
  2. 配置对应的路由,也就是访问我们的域名后,需要执行我们定义的notion worker

    Untitled

    路由为我们的域名加上/*

    Worker为刚才新建的worker

    Untitled

    现在你的个人博客就大功告成了

添加Google Analytics脚本监控你的网站

进入Google Analytics后台 ,点击左上侧管理,选择需要添加代码的网站对应的账号和媒体资源后,依次点击媒体资源下的管理-数据流,可以看到如下所示界面:

Untitled

将如下的代码添加到worker中的自定义片段中就可以对你的博客进行访问监控。

Untitled

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Cloudflare和notion搭建自己的博客 的相关文章

  • 利用ScheduledThreadPoolExecutor定时执行任务

    最近时间好忙 终于抽出时间来写一篇博客了 想了想 把之前遇到的一个小bug分享一下吧 之前在做时钟插件时候 我用到了一个定时器 即大家常用的TimerTask 但它总是意外的停止 就是我开启了一个定时器 每一秒都会走run方法 有时候定时器
  • Wordpress入门建站教程二:搭建WP站点的准备工作

    WordPress入门第一课就简单介绍了WordPress 它是一个使用 PHP语言和 MySQL数据库开发的开源 免费的建站程序 那么搭建WordPress站点 就要求一个能够运行PHP语言的主机空间和一个MySQL数据库 也许有些朋友会
  • js 数组

    1 数组的创建 var arrayObj new Array 创建一个数组 var arrayObj new Array size 创建一个数组并指定长度 注意不是上限 是长度 var arrayObj new Array element0
  • 【公告】博客专家 6 月发布原创/翻译文章奖励

    博客专家6月发布原创 翻译文章奖励 CSDN ID 所获奖励 malefactor 图灵社区技术图书 程序员杂志最新期刊 C币100 lmj623565791 图灵社区技术图书 程序员杂志最新期刊 C币100 jiangwei0910410
  • Java实现压缩解压文件

    关键词 ZipOutputStream ZipInoutStream 最近在工作中有需求需要在浏览器中一次性下载多个文件 于是想到了使用压缩的功能 百度了一下 发现很多博客的内容都大致相同 不太方便使用 于是自己写了这么一个工具类 使用JD
  • 请用美丽欢呼-------Day38

    周末 双休 疯了两天 敲了寥寥的代码 却没少看了相关的文章 这电子书大行于世的年代 对工具的漠然简直就是对生命的亵渎 颠簸的公交车上算是告别了YY的惬意 这生活 感觉傻了点 可真够味 原本只是想写篇 html的发展历程 的 可XHTML 2
  • Django 快速搭建博客 第三节(数据库表设计)

    上一节我们已经能在pycharm下新建了blog app了 这个时候 我们需要设计一下博客的数据库设计 关于数据库表的设计 作为新手的我们并不需要要求懂太多稍微的懂一些也就可以了 毕竟数据库也是需要有一定的功底的 这里我们依据博客学习 将博
  • 51智能小车小车之跟随(超声波的使用)(三)

    智能车的另外一种模式 跟随模式 会跟着前面的障碍物走 此模式利用两个模块 超声波模块和跟随模块 模块的使用 中间是超声波模块 两边是跟随模块 超声波控制前进后退 利用超声波测距 如果距离小于一个值小车前进 否则后退 跟随模块控制左右转动 如
  • 对大连律师李振鹏《甲骨作文,应判“零分”》的反驳

    大连律师李振鹏 甲骨作文 应判 零分 请看http hi baidu com B4 F3 C1 AC C2 C9 CA A6 C0 EE D5 F1 C5 F4 blog item d94cb8fb8bb7b66d034f56c3 html
  • 编码问题

    编码 字符 gt 字节数组 解码 字节数组 gt 字符 编码 String str 你好 byte bus str getBytes UTF 8 解码 String str1 new String bus UTF 8 System out
  • Framework层Android4.4锁屏流程分析

    前段时间刚接触到锁屏 我们自己做的锁屏时通过底层通过反射调过去的 所以还是得从framewoke层的启动和加载开始分析 所以画了一下这样的两个图 前面一个图是系统开机调到锁屏的一个流程 后面一个图我分开来画了 一个是按power键灭屏和亮屏
  • 字符串匹配算法总结

    转自 http blog csdn net zdl1016 archive 2009 10 11 4654061 aspx 我想说一句 我日 我讨厌KMP KMP虽然经典 但是理解起来极其复杂 好不容易理解好了 便起码来巨麻烦 老子就是今天
  • 如何修复自定义 github 页面域上的 ERR_TOO_MANY_REDIRECTS?

    所以我一天前在 namecheap 上设置了自定义域的 github 页面没有问题 然后我尝试通过github新增加的页面对https的支持切换到Https 经过太多的挫折后 我切换到 CloudFlare for Https 但现在遇到错
  • 访问受 Cloudflare 保护的网页

    首先 我想道歉 以防我的问题可能无法提供足够的连接或任何其他问题 我现在正在手机上输入此内容 因此 我正在开发一个项目 需要我在网页中自动执行任务 为了做到这一点 第一步是首先访问该页面 但我遇到了一个障碍 我尝试过搜索和想通了也无济于事
  • 如何阻止 Google Compute Engine 公共 IP 和 GCE 的 cloudflare 白名单?

    我需要阻止 Google Cloud Engine 外部 ip 进行公共访问 我的意思是用户只能通过 cloudflare 上的域访问站点 而不是 GCE 虚拟机实例外部 ip 也许我必须设置 Cloudflare IP 范围 https
  • 由于 cloudflare 无法从 url 读取数据

    每当我编译时 我都会得到这个 线程 main 中的异常 java io IOException 服务器返回 HTTP 响应代码 403 对于 URL 链接 sun net www protocol http HttpURLConnectio
  • 在 GWT 中获取 com.google.gwt.user.client.rpc.StatusCodeException: 0

    我有时 经常在 GWT 中遇到此异常 但不知道为什么 SEVERE com google gwt user client rpc StatusCodeException 0 java lang RuntimeException com go
  • Heroku 不再支持 Cloudflare 背后的 SSL(“CDN 中不支持严格 TLS”)的解决方法?

    几天前 我们在 Cloudflare 代理 橙色云 如果您了解 Cloudflare 后面的 1 个 Heroku 应用程序上收到错误 CDN 中不支持严格 TLS 基本上 客户要求https foo example com https f
  • 使用 Google Cloud + CloudFlare 创建子域

    我在 CloudFlare 上有一个域名 bar com 该域名链接到 Google Cloud 上托管的网站 我可以在 CloudFlare 上为子域名 foo 创建新的 A 记录 但如何将其映射到 Google Cloud 上的 bar
  • 获取请求的客户端 IP 地址而不是 Cloudflare 的 IP 地址

    Cloudflare 会更改传入请求的 IP 地址 因为 Cloudflare 是我的网站和互联网之间的中间件 代理 我该怎么办获取请求的初始IP地址 而不是 Cloudflare 的 IP 地址 我听说过mod cloudflare但是这

随机推荐

  • 数据里面的poi指的什么_如何通过短视频POI功能,获取无数流量

    什么是POI POI功能可以让企业获得独家专享的唯一地址 呈现方式就是抖音视频中的定位图标 点击图标进去 用户可以看到定位这一地址中的全部视频内容 企业通过POI页面可以向用户推荐商品 优惠券 店铺活动等 POI可以让企业和用户之间产生一个
  • 围棋人机大战属于计算机在什么方面的应用,《信息技术基础》第一章复习题库...

    第12题 智能手机 数码相机 MP3播放器等产品中一般都含有嵌入式计算机 答案 Y 第13题 现代遥感遥测技术进步很快 其功能往往远超过人的感觉器官 答案 Y 第14题 集成电路的工作速度主要取决于组成逻辑门电路的晶体管的尺寸 尺寸越小 速
  • ConcurrentHashMap在jdk1.7和jdk1.8中的不同;

    原博客 https www cnblogs com lujiango p 7580558 html http www importnew com 28263 html CouncurrentHashMap 线程安全 一 Councurren
  • Python蒙特卡洛相关变量SciPy模拟

    SciPy 的概率分布和分布拟合 简述 概率分布对随机过程进行建模并将其拟合到观测数据 SciPy 的概率分布 它们的属性和方法 通过拟合 Weibull 极值分布来模拟组件寿命的示例 一个自动化的拟合程序 从大约 60 个候选分布中选择最
  • python logging日志根据等级适配颜色

    安装模块 pip install colorlog 代码参考如下 设置下formatter即可 import logging from colorlog import ColoredFormatter formatter ColoredFo
  • C语言猜数字游戏(详解)

    使用C语言写出猜数字游戏 1 思路 1 我们需要电脑生成一个随机数 2 玩家进行猜数字 3 玩过一次可以再玩一次 那么至少要进去一次 可以使用do while循环 2 大体结构 主函数 使用do while循环 使游戏至少进入一次 然后根据
  • uniapp基于阿里图标库引入彩色的图标iconfont

    1 进入阿里巴巴矢量图标库链接 https www iconfont cn 添加图标到项目 然后下载至本地 2 对下载的文件进行解压 命令行进入解压后的文件下 执行一下命令 全局安装iconfont tools工具 npm install
  • Android编程权威指南第3版 简单的项目作业

    文章目录 前言 1 要求描述 2 MainActivity java 3 InfoActivity java 4 activity info xml 5 activity main xml 6 strings xml 7 AndroidMa
  • Hbase学习笔记(二)——安装与部署

    Hbase 安装与部署 一 安装包 二 修改配置文件 三 分发给其他机器 四 配置环境变量 五 Hbase的启动 一 安装包 hbase 1 2 0 cdh5 14 0 tar gz 二 修改配置文件 配置文件所在位置 cd export
  • 2020美赛MCM/ICM参赛及获奖分析

    文章目录 一 美赛简介 二 参赛队伍数分析 三 选题及获奖情况 四 完整获奖名单pdf 一 美赛简介 美赛 是美国大学生数学建模竞赛的缩写 包括MCM The Mathematical Contest in Modeling数学建模竞赛 和
  • PhpStorm内置的REST客户端 使用方法

    http confluence jetbrains com display PhpStorm Built in REST Client in PhpStorm 跳到元数据结束 由Maarten Balliauw创建 最后由米哈伊尔 温克于2
  • Android之团队开发时高德/百度地图出现INVALID_USER_SCODE

    初次集成前端地图 高德 百度 的同志都可能会遇到INVALID USER SCODE提示 虽然基础地图功能没有影响 但是这个提示直接Toas给用户的 真是够了 如果集成地图导航时可能因为该原因无法打开导航页面 那么我们就研究下为啥出现这个I
  • jQuery实现静态html+ajax请求访问MySQL数据库并显示

    文章目录 静态html ajax与jsp ajax访问流程图 前期准备 配置jQuery 准备index html 准备dao 准备servlet jQuery实现ajax 附 关于Maven项目引入js无法使用的问题 静态html aja
  • Java并发编程与高并发解决方案(精选)

    Java并发编程与高并发面试 一 课程准备 1 1 课程导学 本课程主要是围绕并发编程和高并发解决方案两个核心来进行讲解 希望这门课程能够带领大家攻克并发编程与高并发的难题 课程特点 大量的图示及代码演示 全面覆盖并发知识点 建立完整的知识
  • 计算机操作系统的启动与加载过程

    注 uboot 嵌入式系统的bootloader 包含了BIOS的功能 相当于PC机的BIOS 引导程序
  • MFC的使用——在共享DLL中使用MFC、在静态库中使用MFC

    前言 我们在使用Microsoft Visual Studio软件 也就是我们常常说的VS 时 其中项目属性中有一项叫做 MFC的使用 里面包含有不同的设置 会影响我们所编写的程序的使用 今天我就遇到了这个情况 我们一起来总结一下 避免犯下
  • 数据结构——队列的C语言代码实现

    系列文章目录 数据结构 顺序表的C语言代码实现 数据结构 八种链表的C语言代码实现 数据结构 栈的C语言代码实现 数据结构 队列的C语言代码实现 数据结构 堆的C语言代码实现 文章目录 系列文章目录 前言 一 基础知识 队列的概念 queu
  • pandas时间序列

    目录 1 pandas中6个时间相关的类 2 Timestamp类 1 查看时间列 是str字符串列 还是时间格式列 2 使用pd to datetime 将字符串 转换为日期格式 3 Timestamp类只能表示1677年 2262年的时
  • js 数组移动函数

  • 使用Cloudflare和notion搭建自己的博客

    欢迎访问我的个人博客ximikang icu 使用Cloudflare和notion搭建自己的博客 使用过Nation的小伙伴一定在某个时刻冒出过这样子的想法 这个笔记应用这么好用 而且是基于Web端开发的 那为什么不可以用他来作为我自己的