The project presented in this article is to deploy an errata of your own in a Hexo environment. The code is based on a Github Gist implementation for static blog pages without a backend. Although this approach is easy to implement, please do not use this approach if possible. It is highly recommended that developers who are able to do so look for open text databases on their own, or implement this feature on a backend.
自己学的 HTML 和 Javascript,码风奇丑,请见谅。 这个实现方式,我自己看了都过意不去,都对不起 Github。有能力部署服务器的还是尽可能部署一个,说实话,整多了也不好。
Introduction
This is a blog errata open source project. You can create an errata page in your blog for academic sharing and communication. There are great security risks, so it is not uploaded to Github.
functioncreateXHR() { varXHR=[ function (){returnnewXMLHttpRequest();}, function (){returnnewActiveXObject("Msxml2.XMLHTTP");}, function (){returnnewActiveXObject("Msxml3.XMLHTTP");}, function (){returnnewActiveXObject("Microsoft.XMLHTTP");} ]; var xhr=null; for (let i=0; i<XHR.length; ++i) { try {xhr=XHR[i]();} catch(e) {continue;} break; } return xhr; }
The function createXHR() is used to return an XMLHttpRequest instance, while addToEachLine() inserts the insertString at the beginning of each line in inputString.
These codes are placed in a separate file, which means you can avoid rewriting them when using them in other projects. Of course, you can also combine them into the following file.
Next, create the file source/js/ex-func-errata.js and write the following code in it:
asyncfunctiongetErrata() { const url=`https://api.github.com/gists/${gistId}`; let res; try { const response=awaitfetch(url, { method: 'GET', headers: { 'Authorization': `token ${accessToken}`, 'Accept': 'application/vnd.github.v3+json' } }); if (!response.ok) { console.error('Request Status:', response.status); res='ERR: Request Failed.'; return res; } const data=await response.json(); console.log('Gist Data:', data); try { res=data["files"]["Blog-Errata.txt"]["content"]; } catch (e) { console.error('Request Error.'); res='ERR: Database error, unable to read the errata. Please contact the blog administrator.'; } } catch (e) { console.error('Request Error:', e); res='ERR: Request error, unable to read the errata. Please check your network connection.'; } return res; }
asyncfunctionupdateErrata() { var updateText=`Submitter: ${readSubmitter()}\nIssue Link: ${readLink()}\nIssue Content: \n${addToEachLine(readText(), '\t')}\nStatus: Pending\n----------`; // var res=getErrata(); var res=awaitgetErrata(); if (res.slice(0,4)=='ERR') { return res; } updateText=`${res}\n${updateText}`; console.log(updateText); const requestData={ files: { 'Blog-Errata.txt': { content: updateText } } } const url=`https://api.github.com/gists/${gistId}`; try { const response=awaitfetch(url, { method: 'PATCH', headers: { 'Authorization': `token ${accessToken}`, 'Accept': 'application/vnd.github.raw+json', 'Content-Type': 'application/json' // 'Cache-Control': 'no-cache' // Blocked by CORS Policy }, body: JSON.stringify(requestData) }) if (!response.ok) { console.error('Request Status:', response.status); } const data=response.json(); try { console.log('Update Success:', data); res='Update successful! Please refresh to see the results.' } catch (e) { console.error('Update Error.'); res='Request Error: Database error, unable to read the errata. Please contact the blog administrator.'; } } catch(e) { console.error('Request Error:', e); res='Request error, unable to update the errata. Please check your network connection.'; } return res; }
To get the Github Gist ID, you need to open the Github Gist you created.
For example, here’s a Gist: https://gist.github.com/Username/GistID Its Gist ID is the string at the end: GistID
Your Token Link is a static API that returns your user Token. You can use TextDB to implement this feature, please refer to the API documentation for details. You can choose to update this Token regularly and delete the previous ones to prevent malicious access.
This setup helps protect your Token and complies with Github’s deployment requirements, which do not allow other users’ Tokens to be included.
The code uses techniques related to asynchronous requests. The async-await structure is used here to handle asynchronous requests.
Note the following code:
1 2 3 4
var res=awaitgetErrata(); if (res.slice(0,4)=='ERR') { return res; }
When fetching the errata, if the errata cannot be retrieved, it will not be updated, and an error message will be returned. Without the if statement, your errata might be overwritten by the error message.
Therefore, if you modify the error message, keep the ERR prefix, or alternatively, create a separate flag to indicate the error message.
Edit Page Markdown File
The Markdown file for the new page is at /source/errata/index.md. Edit the following code under YAML Front:
<!-- Prevent refreshing or leaving the page. --> <!-- <script> window.addEventListener('beforeunload', function(e) { var confirmationMessage = 'Refreshing or leaving the page may lose information, are you sure?'; e.returnValue = confirmationMessage; return confirmationMessage; }); </script> -->
<!-- <div class="tip-display-area" id="tipDisplayArea"> Please log in to Github before using it. <button class="login-button" id="loginButton">Login Github</button> </div> -->
Academic use only, please do not upload sensitive and undesirable information.
<div class="text-container"> <!-- Link Single-Line Text Box --> <input class="link-input" id="linkInput" placeholder="Edit the link to the issue page here."></textarea> </div>
<div class="text-container"> <!-- Question Multi-Line Text Box --> <textarea class="text-input" id="textInput" placeholder="Edit the content of the question here."></textarea> </div>
functioncreateXHR() { varXHR=[ function (){returnnewXMLHttpRequest();}, function (){returnnewActiveXObject("Msxml2.XMLHTTP");}, function (){returnnewActiveXObject("Msxml3.XMLHTTP");}, function (){returnnewActiveXObject("Microsoft.XMLHTTP");} ]; var xhr=null; for (let i=0; i<XHR.length; ++i) { try {xhr=XHR[i]();} catch(e) {continue;} break; } return xhr; }