Skip to content

Latest commit

 

History

History
938 lines (699 loc) · 33.7 KB

2022-05-14-hexo搭建next博客.md

File metadata and controls

938 lines (699 loc) · 33.7 KB
title date tags categories
hexo搭建next博客
2022-05-13 21:30:23 -0700
hexo
blog
next themes
hexo

引言

此博客用于搭建 hexo 的工具博客.基本不会探索深究配置的原因,敬请知悉~

hexo 安装

步骤

首先要用 npm 依赖资源管理工具安装全局命令 hexo-cli.

npm install hexo-cli -g

然后使用 hexo 初始化博客目录,比如 blog 目录,目录名要与后续个人建立的 github 上 hexo 托管代码的 repository 同名.

hexo init blog

接着 github 建库.

建立一个以 white-than-wood(我的用户名).github.io 结尾的 repository ,作为 hexo 托管代码的库, github 默认 .github.io 结尾作为用户的网站二级域名,建立一个新的分支作为创作分支(因为主分支是用来发布呈现网站的).

之后,进入生成的 blog 文件夹,与远程 github repository 建立关联,并同步远程最新资源.

git remote add origin git@github.com:white-than-wood/white-than-wood.github.io.git
git pull

再 npm 下载外部依赖包.

npm i/npm install

或者使用 yarn 下载外部依赖包.

yarn

最后启动 hexo 自身搭建的服务,生成本地的博客网站,默认端口在本地 ip 地址下的 4000 端口,假如你不想启动在 4000 端口,也可使用-p 其他端口号进行配置,比如-p 9977.

hexo server
hexo server -p 9977

PS: 最好先将本地代码上传至远程之后,再执行 hexo 配置.

git add .
git commit 'build:搭建hexo个人Github Page博客'
git push --set-upstream origin master

默认的主题风格 theme 是 landscape ,假如你想更换,可以通过https://hexo.io/themes进行筛选,筛选之后进行配置,主题配置见下文.

hexo 命令

示例

首先建立一篇名为 'hexo搭建next博客' 的博客.

hexo new hexo搭建next博客

在根目录 -> source 目录底下的 _post 目录下找到名为 hexo 配置的博客文件,在里面用 markdown 进行记录个人的博客,当然可以在 hexo server 自带的服务器运行监听的情况下,进行添加和修改个人的博客.之后,进行生成静态文件.

hexo generate

生成静态文件之后,进行部署.

hexo deploy

生成静态文件和部署也可以使用一句命令执行.

hexo generate -deploy
hexo deploy -generate

为了防止存在静态文件和缓存,造成没有重新渲染页面的问题,在每一次部署之前,要运行一下清理静态文件和缓存的命令.

hexo clean
hexo generate
hexo deploy

hexo deploy 部署之后,根据项目根目录底下 _config.yml 配置文件的 deploy 配置,会提交到远程 github repository 库.

hexo 配置

PS: 以下所说的"根目录"指的就是当前创作的 repository 目录,"主题目录"就是根目录下/themes目录下的主题环境.

hexo deploy 发布配置

发布部署可以部署至 Github Page 个人网站,也可以部署至个人申请购买的云服务器中.

部署至 Github Page 个人网站.

步骤

要想部署到 Github Page 个人网站,首先要下载 hexo-git 插件.

npm install hexo-deployer-git --save

然后就要在个人的本地hexo博客的项目里面,更改根目录底下的 _config.yml 文件,全局搜索 git ,更改 deploy 发布配置,将 source 目录下面的内容进行构建发布到 repo github 地址的分支上.

deploy:
    type: git
    #你的个人网站 github 库的链接地址,最好使用 git@ 开头的, https@ 开头的会报错
    repo: git@github.com:dreamthen/dreamthen.github.io.git
    #分支名
    branch: master

部署至个人申请购买的云服务器.

步骤

将生成的网站博客项目直接通过 Royal TSX 远程链接管理工具放到云服务器中,链接成功后,下载 nginx 代理.

#我这里直接使用阿里云CentOS服务器中默认的基于RPM的软件包管理器yum来下载nginx
yum install nginx

下载之后查看全局命令 nginx 是否存在,查看 nginx 的版本.

nginx -v

如果全局命令不存在 nginx,则运行 source ~/.bash_profile,使得配置在修改了环境变量的情况下进行重置.

source ~/.bash_profile

启动 nginx.

nginx
  • 顺便提一下 nginx 的其他命令.重启 nginx.

    nginx -s reload
    
  • 停止 nginx.

    nginx -s stop
    
  • 通过流(pipe)查询全部用户组 nginx 完整的进程状态.

    ps -ef | grep nginx
    
  • 强制杀掉 nginx 进程.

    #28009是 nginx 进程号,通过 ps -ef | grep nginx 可以查询到
    kill -9 28009
    

配置 nginx,将服务器代理 root 页面指向我们的网站博客项目.

#通过测试 nginx,查询 nginx 配置文件所在目录
nginx -t
vim /etc/nginx/nginx.conf
  #...
  server {
      listen       80 default_server;
      listen       [::]:80 default_server;
      #域名配置,需要申请购买备案(国内域名需要备案,国外域名则不需要)
      server_name  _;
      #修改root页面向我们的网站博客项目
      root         /usr/share/nginx/html;

      # Load configuration files for the default server block.
      include /etc/nginx/default.d/*.conf;

      location / {
      }

      error_page 404 /404.html;
          location = /40x.html {
      }

      error_page 500 502 503 504 /50x.html;
          location = /50x.html {
      }
  }
  #...

hexo theme 主题配置

示例

筛选好个人选中的主题之后,就需要在项目里面进行配置更换。首先需要下载远程 github 库里面的主题目录到项目根目录里面的 themes 文件夹底下,比如本人用的是 next 主题的 hexo.

git clone https://github.com/iissnan/hexo-theme-next.git themes/next

随后更改根目录里面的 _config.yml 文件,全局搜索 theme ,更改 theme 配置.

theme: next

接着选择主题展示的方式,需要在主题的项目目录下,更改 _config.yml 文件,全局搜索 Scheme ,更改 Scheme 配置,比如 next 主题底下的 Scheme 配置.

scheme:
    #scheme: Muse
    #scheme: Mist
    scheme: Pisces
    #scheme: Gemini

hexo language语言配置

步骤

每个主题的语言都是根据作者的母语来配置的,要想配置开发者个人国家的语言,还是更改项目根目录底下的 _config.yml 文件,全局搜索 language ,更改 language 配置.

language: zh-CN

再更改主题目录底下的 _config.yml 文件,全局搜索 language ,更改 language 配置.

language: zh-CN    

hexo page页面配置

步骤

hexo提供了几个可供筛选的页面,常用的有这么几个:home(首页)、tags(标签)、about(关于我)、archives(档案)和categories(分类),首先要创建页面.

hexo new page tags
hexo new page about
hexo new page archives
hexo new page categories

接着在主题目录下,更改 _config.yml 文件,全局搜索 menu ,更改 menu 配置,当然每个主题的配置不尽相同.

menu:
    home: / || fa fa-home
    about: /about/ || fa fa-user
    tags: /tags/ || fa fa-tags
    categories: /categories/ || fa fa-th
    archives: /archives/ || fa fa-archive

随后更改 source 目录底下创建的页面配置,以 tags 为例.

----------------------------
    title: about
    date: 2018-04-24 17:57:26
    type: "tags"
    comments: false
----------------------------

hexo avatar 头像配置

步骤

配置个人博客网站的头像,需要更改主题目录底下的 _config.yml 文件,添加 avatar 配置.

#头像url链接
avatar: https://avatars.githubusercontent.com/u/11425476?v=4

hexo search 全站搜索配置

步骤

假如想要配置hexo个人博客网站的全站搜索配置,首先要下载 hexo search 外部依赖包.

npm install hexo-generator-search --save
npm install hexo-generator-searchdb --save

更改根目录底下的 _config.yml 文件,添加 search 配置.

search:
    path: search.xml
    field: post
    format: html
    limit: 10000

开启主题目录底下的 _config.yml 文件中的 local_search 配置.

local_search:
    enable: true        

hexo new_post_name配置

步骤

假如想要更改每一篇博客的文件名称,不再是默认的:title.md的文件名,需要更改根目录底下的 _config.yml 文件,更改 new_post_name 配置.

new_post_name: :year-:month-:day-:title.md

hexo auto_excerpt阅读全文配置

步骤

博客文章一般都会很长的,所以在首页要对博客进行超长省略,要想看所有的内容,点击阅读全文或者文章标题进入全文查看.在 hexo-theme-next 主题版本7.6之前需要更改主题目录底下的 _config.yml 文件,全局搜索 auto_excerpt ,更改 auto_excerpt 配置.

auto_excerpt:
    enable: true
    length: 200

在 hexo-theme-next 主题版本7.6之后,由于 auto_excerpt 这种超长省略不应该是主题插件应该做的,作者将此配置移除,并给出新的专门针对此配置的插件 hexo-excerpt.

excerpt:
    #显示的 markdown 代码块层数
    depth: 5
    excerpt_excludes: []
    more_excludes: []
    #设置为true: 显示超长省略,只展示部分,隐藏全文
    #设置为false: 展示全文
    hideWholePostExcerpts: true
    excerpt_description: true
    #是否显示阅读全文按钮
    read_more_btn: true

hexo browsersync开发环境创作自动更新配置

步骤

在创作博客时,需要每次手动刷新页面才能看到修改后的结果,感觉非常没有效率,如果存在类hrm热加载这种插件就太爽了! hexo-browsersync 可以直接解决这个问题.

此插件原理基于 browser-sync ,与 hexo 建立关联,当创作的文件内容发生改变时, browser-sync 就会监听到并刷新浏览器整个页面的内容,做到不需手动刷新,大大提高了创作效率.

#更改根目录底下的 _config.yml 文件,添加 browsersync 属性
#设置监听 watch 属性为 true 就可以了!
browsersync:
    watch: true
    logLevel: "warn"

hexo busuanzi_count卜算子统计配置

步骤

上线之后,需要对个人博客进行管理,阅读人数以及次数对于创作者来说是很重要反馈点.统计配置需要更改主题目录底下的 _config.yml 文件,配置 busuanzi_count 卜算子统计.

#可配置查看个人博客的阅读人数、次数以及每篇博客文章的次数
busuanzi_count:
    enable: true
    total_visitors: true
    total_visitors_icon: fa fa-user
    total_views: true
    total_views_icon: fa fa-eye
    post_views: true
    post_views_icon: fa fa-eye

hexo baidu_analytics百度统计配置

步骤

卜算子统计有时候会出现一些异常,比如pv莫名会加100,uv不再区分单个ip.为了追求更精确、更智能,我们采用百度统计. 统计配置需要更改主题目录底下的 _config.yml 文件,配置 baidu_analytics 百度统计.

根据百度统计-使用配置-代码获取,将hm.js后方自动生成的id配置至baidu_analytics.

# Baidu Analytics
# See: https://tongji.baidu.com
baidu_analytics: 31f07c2ec89d10385ec28e8eea5bbc3a

hexo Gitalk留言板配置

步骤

留言板 comments 是创作者与阅读者进行互动反馈的窗口,可以使阅读者与创作者共同进步.对于 hexo 来说,支持的留言板模式有很多种: 'disqus | disqusjs | changyan | livere | gitalk | utterances' ,比较常见、用户量比较大且与github关联性比较强的就是 gitalk 以及 disqus,disqusjs 需要'梯子'🐶才能评论,那么还是选用 gitalk .留言板配置需要更改主题目录下的 _config.yml 文件.

配置comments:

# Multiple Comment System Support
comments:
    # Available values: tabs | buttons
    style: tabs
    # Choose a comment system to be displayed by default.
    # Available values: disqus | disqusjs | changyan | livere | gitalk | utterances
    active: gitalk
    # Setting `true` means remembering the comment system selected by the visitor.
    storage: true
    # Lazyload all comment systems.
    lazyload: false
    # Modify texts or order for any naves, here are some examples.
    nav:
        gitalk:
            order: -2
        disqus:
            text: Load Disqus
            order: -1

配置gitalk:

# Gitalk
# For more information: https://gitalk.github.io
gitalk:
    enable: true
    github_id: white-than-wood # GitHub repo owner
    repo: white-than-wood.github.io # Repository name to store issues
    client_id: 1191ab5290535c1acb09 # GitHub Application Client ID
    client_secret: 8d2cbebac1ae1230f84d1f9f7a36f8008a42c14b # GitHub Application Client Secret
    admin_user: white-than-wood # GitHub repo owner and collaborators, only these guys can initialize gitHub issues
    distraction_free_mode: true # Facebook-like distraction free mode
    # When the official proxy is not available, you can change it to your own proxy address
    proxy: https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
    # proxy: login/oauth/access_token # This is official proxy address
    # Gitalk's display language depends on user's browser or system environment
    # If you want everyone visiting your site to see a uniform language, you can set a force language value
    # Available values: en | es-ES | fr | ru | zh-CN | zh-TW
    language: zh-CN

上面的配置项中有几个需要说明的:

  • client_id 与 client_secret 是 Github 的 OAuth 认证(下一个部分会介绍).
  • github_id 与 admin_user 这里建议填一样,填成个人的 github 账号名(不是邮箱,也不是用户名).
  • proxy 默认即是上面的地址,它其实会回调到这里https://github.com/login/oauth/access_token.
  • 无论是部署至 GitHub Page 个人网站,还是部署至个人申请购买的云服务器,上面三点是必须要实行的,proxy 403 问题主要是在部署至个人申请购买的云服务器中时会遇到,部署至 GitHub Page 个人网站不能进行自定义配置反向代理,所以只能使用 Gitalk 官方搭建的代理.

Github 的 OAuth 认证.

前提是得有一个 github 账号,才能注册 OAuth application ,这是 OAuth 应用注册地址.

PS: 如果有自定义域名(如个人申请的阿里云域名),则在上图中填入自定义域名.

注册之后,点击下图中'Generate a new client secret'按钮,在个人账号下的Settings -> Developer settings -> OAuth Apps下面可以查看 OAuth 认证 client_id 与 client_secret.

Gitalk 自动初始化.

原理: 通过 sitemap 中的信息,请求 github 开放 api 达到自动产生 issues 的目的.
基本的要求: github API 需要请求 token.

  • 申请 github Token.

    我们需要使用 Personal access tokens 方式,这种方式限制每小时5000次,结合缓存功能,基本满足需求. 从 Github 的 Personal access tokens 页面,点击 Generate new token.

  • 安装 npm 依赖项.

    npm i -D md5 moment request xml-parser
    npm i -S hexo-generator-sitemap
    
  • 配置 sitemap.

    在根目录中创建 sitemap_template.xml.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for post in posts %}
<url>
 <loc>{{ post.permalink | uriencode }}</loc>
 {% if post.updated %}
 <lastmod>{{ post.updated.toISOString() }}</lastmod>
 {% elif post.date %}
 <lastmod>{{ post.date.toISOString() }}</lastmod>
 {% endif %}
 <date>{{ post.date }}</date>
 <title>{{ post.title + ' | ' + config.title }}</title>
 {# nunjucks 模版语法 https://github.com/mozilla/nunjucks #}
 <desc>{{ post.description | default(post.excerpt) | default(post.content) | default(config.description) | striptags | truncate(200, true, '') }}</desc>
</url>
{% endfor %}
</urlset>
  • 修改根目录下的 _config.yml.
#Sitemap
sitemap:
    path: sitemap.xml
    template: ./sitemap_template.xml
    rel: false
    tag: true
    category: false
  • 生成 sitemap.xml 文件.
hexo clean && hexo generate
  • 根目录添加 talk-auto-init.js (注意还是不要将此文件置于github中,建议ignore).
const fs = require('fs');
const path = require('path');
const url = require('url');

const request = require('request');
const xmlParser = require('xml-parser');
const md5 = require('md5');

// 配置信息
const config = {
username: 'white-than-wood', // GitHub repository 所有者,可以是个人或者组织。对应 Gitalk 配置中的 owner
repo: "white-than-wood.github.io", // 储存评论 issue 的 github 仓库名,仅需要仓库名字即可。对应 Gitalk 配置中的 repo
token: 'ghp_EuXHDkOxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // 前面申请的 personal access token
sitemap: path.join(__dirname, './public/sitemap.xml'), // 个人站点的 sitemap 文件地址
cache: true, // 是否启用缓存,启用缓存会将已经初始化的数据写入配置的 gitalkCacheFile 文件,下一次直接通过缓存文件判断
gitalkCacheFile: path.join(__dirname, './gitalk-init-cache.json'), // 用于保存 gitalk 已经初始化的 id 列表
gitalkErrorFile: path.join(__dirname, './gitalk-init-error.json'), // 用于保存 gitalk 初始化报错的数据
};

const api = 'https://api.github.com/repos/' + config.username + '/' + config.repo + '/issues';

/**
* 读取 sitemap 文件
* 远程 sitemap 文件获取可参考 https://www.npmjs.com/package/sitemapper
*/
const sitemapXmlReader = (file) => {
try {
 const data = fs.readFileSync(file, 'utf8');
 const sitemap = xmlParser(data);
 let ret = [];
 sitemap.root.children.forEach(function (url) {
   const loc = url.children.find(function (item) {
     return item.name === 'loc';
   });
   if (!loc) {
     return false;
   }
   const title = url.children.find(function (item) {
     return item.name === 'title';
   });
   const desc = url.children.find(function (item) {
     return item.name === 'desc';
   });
   const date = url.children.find(function (item) {
     return item.name === 'date';
   });
   ret.push({
     url: loc.content,
     title: title.content,
     desc: desc.content,
     date: date.content,
   });
 });
 return ret;
} catch (e) {
 return [];
}
};

// 获取 gitalk 使用的 id
const getGitalkId = ({
                    url: u,
                    date
                  }) => {
const link = url.parse(u);
// 链接不存在,不需要初始化
if (!link || !link.pathname) {
 return false;
}
if (!date) {
 return false;
}
return md5(link.pathname);
};

/**
* 通过以请求判断是否已经初始化
* @param {string} gitalk 初始化的id
* @return {[boolean, boolean]} 第一个值表示是否出错,第二个值 false 表示没初始化, true 表示已经初始化
*/
const getIsInitByRequest = (id) => {
const options = {
 headers: {
   'Authorization': 'token ' + config.token,
   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
   'Accept': 'application/json'
 },
 url: api + '?labels=' + id + ',Gitalk',
 method: 'GET'
};
return new Promise((resolve) => {
 request(options, function (err, response, body) {
   if (err) {
     return resolve([err, false]);
   }
   if (response.statusCode != 200) {
     return resolve([response, false]);
   }
   const res = JSON.parse(body);
   if (res.length > 0) {
     return resolve([false, true]);
   }
   return resolve([false, false]);
 });
});
};

/**
* 通过缓存判断是否已经初始化
* @param {string} gitalk 初始化的id
* @return {boolean} false 表示没初始化, true 表示已经初始化
*/
const getIsInitByCache = (() => {
// 判断缓存文件是否存在
let gitalkCache = false;
try {
 gitalkCache = require(config.gitalkCacheFile);
} catch (e) {}
return function (id) {
 if (!gitalkCache) {
   return false;
 }
 if (gitalkCache.find(({
                         id: itemId
                       }) => (itemId === id))) {
   return true;
 }
 return false;
};
})();

// 根据缓存,判断链接是否已经初始化
// 第一个值表示是否出错,第二个值 false 表示没初始化, true 表示已经初始化
const idIsInit = async (id) => {
if (!config.cache) {
 return await getIsInitByRequest(id);
}
// 如果通过缓存查询到的数据是未初始化,则再通过请求判断是否已经初始化,防止多次初始化
if (getIsInitByCache(id) === false) {
 return await getIsInitByRequest(id);
}
return [false, true];
};

// 初始化
const gitalkInit = ({
                   url,
                   id,
                   title,
                   desc
                 }) => {
//创建issue
const reqBody = {
 'title': title,
 'labels': [id, 'Gitalk'],
 'body': url + '\r\n\r\n' + desc
};

const options = {
 headers: {
   'Authorization': 'token ' + config.token,
   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
   'Accept': 'application/json',
   'Content-Type': 'application/json;charset=UTF-8'
 },
 url: api,
 body: JSON.stringify(reqBody),
 method: 'POST'
};
return new Promise((resolve) => {
 request(options, function (err, response, body) {
   if (err) {
     return resolve([err, false]);
   }
   if (response.statusCode != 201) {
     return resolve([response, false]);
   }
   return resolve([false, true]);
 });
});
};


/**
* 写入内容
* @param {string} fileName 文件名
* @param {string} content 内容
*/
const write = async (fileName, content, flag = 'w+') => {
return new Promise((resolve) => {
 fs.open(fileName, flag, function (err, fd) {
   if (err) {
     resolve([err, false]);
     return;
   }
   fs.writeFile(fd, content, function (err) {
     if (err) {
       resolve([err, false]);
       return;
     }
     fs.close(fd, (err) => {
       if (err) {
         resolve([err, false]);
         return;
       }
     });
     resolve([false, true]);
   });
 });
});
};

const init = async () => {
const urls = sitemapXmlReader(config.sitemap);
// 报错的数据
const errorData = [];
// 已经初始化的数据
const initializedData = [];
// 成功初始化数据
const successData = [];
for (const item of urls) {
 const {
   url,
   date,
   title,
   desc
 } = item;
 const id = getGitalkId({
   url,
   date
 });
 if (!id) {
   console.log(`id: 生成失败 [ ${id} ] `);
   errorData.push({
     ...item,
     info: 'id 生成失败',
   });
   continue;
 }
 const [err, res] = await idIsInit(id);
 if (err) {
   console.log(`Error: 查询评论异常 [ ${title} ] , 信息:`, err || '无');
   errorData.push({
     ...item,
     info: '查询评论异常',
   });
   continue;
 }
 if (res === true) {
   // console.log(`--- Gitalk 已经初始化 --- [ ${title} ] `);
   initializedData.push({
     id,
     url,
     title,
   });
   continue;
 }
 console.log(`Gitalk 初始化开始... [ ${title} ] `);
 const [e, r] = await gitalkInit({
   id,
   url,
   title,
   desc
 });
 if (e || !r) {
   console.log(`Error: Gitalk 初始化异常 [ ${title} ] , 信息:`, e || '无');
   errorData.push({
     ...item,
     info: '初始化异常',
   });
   continue;
 }
 successData.push({
   id,
   url,
   title,
 });
 console.log(`Gitalk 初始化成功! [ ${title} ] - ${id}`);
 continue;
}

console.log(''); // 空输出,用于换行
console.log('--------- 运行结果 ---------');
console.log(''); // 空输出,用于换行

if (errorData.length !== 0) {
 console.log(`报错数据: ${errorData.length} 条。参考文件 ${config.gitalkErrorFile}。`);
 await write(config.gitalkErrorFile, JSON.stringify(errorData, null, 2));
}

console.log(`本次成功: ${successData.length} 条。`);

// 写入缓存
if (config.cache) {
 console.log(`写入缓存: ${(initializedData.length + successData.length)} 条,已初始化 ${initializedData.length} 条,本次成功: ${successData.length} 条。参考文件 ${config.gitalkCacheFile}。`);
 await write(config.gitalkCacheFile, JSON.stringify(initializedData.concat(successData), null, 2));
} else {
 console.log(`已初始化: ${initializedData.length} 条。`);
}
};

init();
  • 修改 package.json 中 scripts 中的脚本,添加 "gitalk":"node talk-auto-init.js".
{
"scripts": {
   "build": "hexo generate",
   "clean": "hexo clean",
   "deploy": "hexo deploy",
   "server": "hexo server",
   "publish": "git push && hexo clean && hexo generate -deploy",
   "gitalk": "node talk-auto-init.js"
}
}
  • 测试 gitalk.
npm run talk
  • 已经缓存过后的结果:
> hexo-site@0.0.0 gitalk
> node talk-auto-init.js


--------- 运行结果 ---------

本次成功: 0 条。
写入缓存: 7 条,已初始化 7 条,本次成功: 0 条。参考文件 /Users/yinwk/keryi/white-than-wood.github.io/gitalk-init-cache.json.

proxy 403错误

部署至个人申请购买的云服务器时,由于跨域问题,会出现 proxy 403 forbidden.解决它主要有这么几个方案.

  • nginx反向代理 解决方案(推荐).

    在云服务器 nginx 的博客配置中加入如下内容(注意个人博客的域名必须经过 https ssl 安全证书备案).

server {
 listen 443 ssl http2;
 #...
 location = /login/oauth/access_token {
     add_header Access-Control-Allow-Origin 'https://white-than-wood.zone/';  //这里改成个人的域名,并删除注释
     add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
     add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
     if ($request_method = 'OPTIONS') {
           return 204;
     }
     proxy_pass https://github.com/;
 }
 #...
}

PS: nginx 反向代理之后,要将 proxy 指向代理域名下的链接回调进行修改.

proxy: https://white-than-wood.zone/https://github.com/login/oauth/access_token
  • 自建一个 workers.

    地址: CloudFlare Workers. 参考文章: 使用 CloudFlare Workers 实现 CORS Anywhere.

  • 使用其他人搭建的代理.

    比如这个 issues 介绍到的:

     proxy: https://shielded-brushlands-08810.herokuapp.com/https://github.com/login/oauth/access_token
    
  • 使用 Gitalk 官方搭建的代理.

    据gitalk issue gitalk 授权登录后报错403,直接将使用 Gitalk 官方搭建的代理就可解决 403 forbidden 的问题,之前 Gitalk 官方搭建的代理由于太多人接入导致被官方限制使用,用户经常发现不能正常使用,现在已经对代理进行优化改进,不会出现限制使用的情况.

     https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
    
  • 更新 gitalk 版本至1.7.2.

    据gitalk issue gitalk 授权登录后报错403,直接将 gitalk 版本升级至1.7.2就可解决 403 forbidden 的问题.

hexo GitHub Page个人网站自定义域名

部署至 GitHub Page 个人网站配置自定义域名时,需要将个人申请购买的域名(最好是通过 https ssl 安全证书备案)进行域名解析,GitHub Page也需要CNAME配置.

阿里云域名解析.

步骤

域名解析简单来说实际上就是通过配置,可以使用不同的域名访问同一网站.首先进入阿里云服务管理平台,对已经申请购买的域名进行解析.

添加记录或者对某一个列表项进行修改.可以使用 A记录 也可以使用 CNAME.

A记录是将域名指向一个IPV4地址.
CNAME是将域名指向另外一个域名.

这里使用的是 A记录,将 white-than-wood.github.io 的 IP 地址作为记录值.

ping white-than-wood.github.io

主机记录,解析后的域名基本上就两种,'@'和'www'.

'@' 是源域名(主域名 white-than-wood.zone).
'www' 则是 www.white-than-wood.zone.

GitHub Page个人网站CNAME配置.

在 source 目录下新建 CNAME 文件(不带任何后缀),在文件内写入你的主域名.

  white-than-wood.zone

或者在 Github Page 个人配置下设置自定义域名,Github 会自动添加 CNAME 文件.

这两种方式我这边是全部使用的.全部搞定之后,就可以通过 white-than-wood.zone 访问 white-than-wood.github.io GitHub Page 个人网站.

延伸

既然已经通过阿里云服务 A记录 或者 CNAME 解析域名,为什么还需要在 GitHub Page 个人网站上配置 CNAME ?

云服务 A记录 或者 CNAME 域名解析至 GitHub Page,通过 white-than-wood.zone 可以访问 GitHub Page 个人网站,那原来的 white-than-wood.github.io 域名怎么办呢? GitHub Page 也通过 CNAME 域名解析至 white-than-wood.zone. 使得 github.io 域名也可以直接访问个人申请购买的域名.

hexo 其他配置

示例

更改根目录底下的 _config.yml 文件,更改网站title(标题)、author(作者)、keywords(关键字)、description(描述)配置,比如本人的配置.

title: WTW's Frontend
author: WTW(比木白)
keywords: hexo,hexo-cli,hexo博客,hexo博客个人网站,hexo blog
subtitle: 道阻且长,行则将至
description: 前端领域内所不知道的都探索于此!

更改主题目录底下的 _config.yml 文件,设置个人的github(github托管代码网址)、google(google个人资料网址)、gmail(gmail邮箱网址)、twitter(twitter个人微博网址)等等,比如本人的配置.

social:
  GitHub: https://github.com/white-than-wood || fab fa-github
  E-Mail: https://dreamthen.00@gmail.com || fab fa-envelope
  Google: https://plus.google.com/u/0/103833130011211353424 || fab fa-google

发布到 GitHub Page 上之后,你会发现 README.md 莫名的消失,主要是因为 hexo 构建发布到远程的目录只是 source 目录,所以只要将 README.md copy 一份放到 source 目录下,并且配置渲染时跳过的 markdown 类型文件就可以了.

#hexo构建渲染时会将source目录下markdown类型文件转译为html,我们不需要将README.md转译,所以直接skip render
#更改根目录底下的_config.yml文件,修改skip_render属性
skip_render: README.md

当创作中图片过小,阅读者无法看清的情况下,放大配置就已然成为必要 .fancybox 配置可以点击使图片放大,并可同时查看全文的图片.更改主题目录下的 _config.yml 文件 fancybox 属性.

# FancyBox is a tool that offers a nice and elegant way to add zooming functionality for images.
# For more information: https://fancyapps.com/fancybox/
fancybox: true