自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何通過 GitHub API 獲取較大的文件

譯文 精選
開發(fā)
我在 Hackernoon 上有一個任務,該任務需要使用 GitHub API 獲取一些文件。起初,我認為這將會是一個簡單的 GET 請求,但很快我意識到是我把問題想簡單了。

我在 Hackernoon 上有一個任務,該任務需要使用 GitHub API 獲取一些文件。起初,我認為這將會是一個簡單的 GET 請求,但很快我意識到是我把問題想簡單了。從剛開始 GET 請求的結果來看,我需要使用一些我目前還沒有掌握的方法,因為需要獲取的文件非常大,最終在這個問題上我花費了兩天的時間。

現(xiàn)在是時候寫一篇文章了,這樣以后我和其他人就都不必在一個簡單的問題上花費太多時間了。

在本文中,我將向您展示如何使用 GitHub API 獲取大于 1MB 的文件。學習完本文章后,您將會了解以下內容:

  • 如何使用 GitHub API 獲取大文件
  • 如何使用commit SHA
  • 使用 blob  base64 編碼數(shù)據(jù)

在本文中,我將使用了來自 HackerNoon 的年度創(chuàng)業(yè)大賽(https://startups.hackernoon.com/faq?ref=hackernoon.com)的數(shù)據(jù)。 該部分數(shù)據(jù)在 GitHub上是公開的。

獲取小于1MB的文件

獲取較小的文件很簡單,您只需將三個參數(shù)傳遞給 API。 首先是所有者的姓名,可以是您的用戶名。第二個是 repo,它是提交文件的存儲庫。path 是文件的絕對路徑。

下面是我使用codepen創(chuàng)建的一小段代碼,供大家參考。

let fileSHA, fileBlob, fileContent, file

const getFileSHA = async () => {
try {
const response = await fetch(
"https://api.github.com/repos/hackernoon/where-startups-trend/contents/2021/"
);
const data = await response.json();
// console.log(data);

fileSHA = data[1].sha
console.log(fileSHA);

} catch (error) {
console.log(error);
}

getFileBlob()
}

const getFileBlob = async (fileSHA)=> {
try {
const response = await fetch(
`https://api.github.com/repos/hackernoon/where-startups-trend/git/blobs/a51a49dfc2bd7be262bd59bb85e85271ea0c18cd`
);
const data = await response.json();

fileBlob = data.content
convertBlob(fileBlob)
} catch (error) {
console.log(error);
}
}

const convertBlob = async blob => {
// console.log(blob)
try {

// const fileContents = Buffer.from(blob, "base64").toString()
// file = JSON.parse(fileContents)
// file = JSON.parse(fileContents)

fileContents = base64EncodeUnicode(blob)
file = JSON.parse(fileContents)
console.log(file)

} catch(error) {
console.log(error)
}
}

function base64EncodeUnicode(str) {
utf8Bytes = decodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
return String.fromCharCode('0x' + p1);
});

return atob(utf8Bytes);
}


getFileSHA()

為了更好地理解上述代碼,我創(chuàng)建了四個變量,用來存儲不同狀態(tài)下的數(shù)據(jù)。

let fileSHA, fileBlob, fileContent, file
  • fileSHA用來存儲我們想要獲取的文件的 SHA
  • fileBlob存儲從API 獲取的 blob。
  • fileContent用于存儲解碼后的字符串。
  • file包含我們真正需要的數(shù)據(jù)。

您可以在下一節(jié)中找到對應的參考代碼,只需將文件夾路徑更改為實際文件路徑(帶文件擴展名)。

獲取大文件

但是,如果您需要獲取大于 1MB 的文件,API 會拋出錯誤。這是因為上述方式不支持大文件。若需要獲取大文件,我們必須改為使用 Github API。

這類API允許您從 Git 存儲庫和列表中讀取和寫入原始 Git 對象,也可以更新 Git 引用(Git references)。 該類API主要適用于blob,這正是本文的重點。

Git將大文件轉換為base64 編碼的 blob,而不是存儲整個文件,以便獲得更好的性能。因此,當您請求同一個文件時,希望您使用返回 blob的接口。

要獲取blob,您需要傳遞文件對應的SHA。您可能想問,什么是 SHA?又該如何獲得它?

每次提交新文件時,git 都會創(chuàng)建一個名為 hash 或 SHA 的唯一ID 來記錄此次更改。但有時可能會導致問題,我將在本文末尾討論這個問題。

獲取文件對應的SHA

現(xiàn)在,我們需要找到一種方法來獲取所需文件的“SHA”。GitHub API有一個接口,可以用來同我們需要使用的文件內容進行交互。

GET /repos/{owner}/{repo}/contents/{path}

作為響應,我們得到一個有關對象的數(shù)組,其中包含目錄中每個文件的元數(shù)據(jù)。 元數(shù)據(jù)中包含我們可以存儲和后面會用到的SHA。

const getFileSHA = async () => {
try {
const response = await fetch(
"<https://api.github.com/repos/hackernoon/where-startups-trend/contents/2021/>"
);
const data = await response.json();
console.log(data);

fileSHA = data[3].sha
console.log(fileSHA);

} catch (error) {
console.log(error);
}

getFileBlob(fileSHA)
}

data[3].sha 是具有 votes_by_region.jso n 的 SHA,因此我們將其存儲在 fileSHA 中以備后面使用。 下圖是控制臺的輸出情況:

獲取對應的Blob

我們已經獲取了blob所需SHA。 我們需要使用不同的接口來處理 blob。 這個接口與上一個接口相似,但該接口需要將文件對應的SHA 作為第三個參數(shù)傳遞。

GET /repos/{owner}/{repo}/git/blobs/{file_sha}

當我們向下面的函數(shù)提供文件的 SHA 作為參數(shù)時,就可以獲取對應blob。

const getFileBlob = async (fileSHA)=> {
try {
const response = await fetch(
`https://api.github.com/repos/hackernoon/where-startups-trend/git/blobs/${fileSHA}`
);
const data = await response.json();

fileBlob = data.content
convertBlob(fileBlob)
} catch (error) {
console.log(error);
}
}

此請求返回一個 base64 編碼的 blob。 Base64 是一種以 ASCII 字符串格式表示二進制數(shù)據(jù)的編碼方案。 當我們需要在不進行任何修改的情況下存儲或傳輸數(shù)據(jù)時,它很有用??刂婆_輸出看起來很亂,但這就是 base64 編碼數(shù)據(jù)的方式。

將 Blob 轉換為可使用的數(shù)據(jù)

在最后一步,我們需要將以 base64 編碼的 blob 轉換為我們可以在程序中使用的數(shù)據(jù)。 但這一步非常令人沮喪,因為標準方法在某些情況下似乎不起作用。在這個問題上花了幾個小時后,我找到了三個解決方案。

1.最簡單的方法

這是 JavaScript 原生支持的標準方式。 atob() 是一個 Web API 接口,可將 base64 編碼數(shù)據(jù)解碼為純字符串。

atob 把讀取的 ASCII 轉化為二進制,因為它將以 ASCII 編碼的 base64 數(shù)據(jù)轉換為二進制形式。 輸出將是一個解碼后的字符串。 要將其轉換為其原始數(shù)據(jù)類型,我們使用 JSON.parse()。

fileContents = atob(blob)
file = JSON.parse(fileContents)

2.第二種方法

如果上述方法拋出錯誤,你可以使用Node.js 提供了一個方法 Buffer.from()。 它將要解碼的字符串作為第一個參數(shù),將編碼技術作為第二個參數(shù)。

try {
const fileContents = Buffer.from(fileBlob, "base64").toString()
file = JSON.parse(blobToString)

console.log(file)
} catch(error) {
console.log(error)
}

3.第三種方法

如果您在前端工作,則前面提到的方法很有可能不起作用。 在這種情況下,創(chuàng)建一個使用 decodeURIComponent 的函數(shù)。

// define the function
const decodeBase64 = str => {
utf8Bytes = decodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
return String.fromCharCode('0x' + p1);
});

return atob(utf8Bytes);
}

您可以通過傳遞 fileBlob 作為參數(shù)來調用此函數(shù),并獲取您需要的解碼字符串。

fileContents = decodeBase64(fileBlob)
file = JSON.parse(fileContents)

console.log(file)

依然不能正常工作

此時,您可以嘗試兩種最終選擇。您可以使用 FileReader API 或以不同的方式使用 decodeURIComponent。

1.FileReader API:您可以在此處找到 MDN 文檔(https://developer.mozilla.org/en-US/docs/Web/API/FileReader?ref=hackernoon.com)

2.decodeURIComponent:請參閱 Rajeev Singh關于處理 16 位編碼字符串的博客。(https://www.base64decoder.io/javascript/?ref=hackernoon.com)

或者,您也可以嘗試一個名為 js-base64(https://www.npmjs.com/package/js-base64?ref=hackernoon.com)的 NPM 包。我自己沒有使用過,所以無法提供建設性的意見。

注意

如前所述,SHA 是在每次修改文件時都會更改的具有唯一性的ID號。此外,由于我們在 getFileSHA() 函數(shù)中有一個硬編碼的對象索引,如果您在目錄中添加或刪除文件,API 可能會以不同文件的 SHA 響應。

為了解決這個問題,您可以明確指明的文件名而不是索引,這樣您就可以在提交新更改后保持函數(shù)不變。

總結和 TL;DR

1.Git 以 blob 格式存儲較大的文件,因此我們使用 GitHub 數(shù)據(jù)庫 API 來獲取大于 1MB 的文件。

2.我們需要提供用戶名、repo 名稱和文件的 SHA 來獲取 blob。

3.為了獲取 SHA,我們需要向接口提供文件夾路徑并將其存儲在變量中。

4.之后我們需要將 SHA 作為參數(shù)傳遞給另一個接口并獲得一個 base64 編碼的 blob。

5.必須將 blob 解碼為純字符串,然后使用 JSON.parse() 將其轉換為原始格式,然后才能使用它。

更多參考資料

GitHub 存儲庫的內容(https://docs.github.com/en/rest/reference/repos?ref=hackernoon.com#contents)

Git 數(shù)據(jù)庫(https://docs.github.com/en/rest/reference/git?ref=hackernoon.com)

Git 數(shù)據(jù)庫 API 入門(https://docs.github.com/en/rest/guides/getting-started-with-the-git-database-api?ref=hackernoon.com)

譯者介紹

趙青窕,51CTO社區(qū)編輯,從事多年驅動開發(fā)。研究興趣包含安全OS和網絡安全領域,發(fā)表過網絡相關專利。

原文標題:??How to Fetch Large Data Files Through GitHub API??,作者:Kaushal Joshi

責任編輯:莫奇 來源: 51CTO
相關推薦

2012-11-23 14:27:43

IBMdW

2023-03-01 15:52:30

2014-09-01 09:49:24

github

2021-05-11 19:58:01

身份驗證Code

2018-06-19 08:12:25

2018-06-22 10:18:52

2018-05-03 09:43:07

Linux命令傳輸文件

2021-06-28 11:50:07

APIHTTP網絡協(xié)議

2022-09-05 07:32:46

mock數(shù)據(jù)Stream

2022-09-22 15:29:17

public-SDK應用開發(fā)

2013-04-03 12:53:23

Android開發(fā)shared_user

2009-03-14 16:03:50

AccessMSSQL漏洞

2020-10-12 09:46:34

漏洞

2022-11-04 10:49:56

Linux文件

2012-09-11 11:08:23

Github系統(tǒng)

2009-08-05 15:37:01

調用Windows A隱藏GoogleEar

2020-08-26 10:41:29

云計算投資云應用

2020-04-29 10:35:45

遠程工作員工CIO

2012-03-08 09:44:41

編程

2021-12-02 07:02:16

API性能設計
點贊
收藏

51CTO技術棧公眾號