当前位置: 首页 > 科技观察

如何通过GitHubAPI获取大文件

时间:2023-03-15 08:57:22 科技观察

我在Hackernoon上有一个任务需要使用GitHubAPI获取一些文件。起初,我认为这将是一个简单的GET请求,但很快我就意识到我对这个问题想得太多了。从一开始GET请求的结果来看,需要用到一些自己还没有掌握的方法,因为需要获取的文件非常大,最后在这个问题上花了两天时间。现在是时候写一篇文章了,这样以后我和其他人都不必花太多时间在一个简单的问题上。在本文中,我将向您展示如何使用GitHubAPI获取大于1MB的文件。学习本文后,您将了解以下内容:如何使用GitHubAPI获取大文件如何使用commitSHA对带有blob和base64的数据进行编码hackernoon.com/faq?ref=hackernoon.com)。这部分数据在GitHub上是公开的。获取小于1MB的文件获取更小的文件很简单,您只需要将三个参数传递给API。首先是所有者的姓名,可以是您的用户名。第二个是repo,它是提交文件的存储库。path是文件的绝对路径。下面是我使用codepen创建的一小段代码供您参考。让fileSHA,fileBlob,fileContent,fileconstgetFileSHA=async()=>{try{constresponse=awaitfetch("https://api.github.com/repos/hackernoon/where-startups-trend/contents/2021/");constdata=awaitresponse.json();//控制台日志(数据);fileSHA=data[1].shaconsole.log(fileSHA);}赶上(错误){console.log(错误);}getFileBlob()}constgetFileBlob=async(fileSHA)=>{try{constresponse=awaitfetch(`https://api.github.com/repos/hackernoon/where-startups-trend/git/blobs/a51a49dfc2bd7be262bd59bb85e85271ea0c18cd`);constdata=awaitresponse.json();fileBlob=data.contentconvertBlob(fileBlob)}catch(error){console.log(error);}}constconvertBlob=asyncblob=>{//console.log(blob)try{//constfileContents=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)}}functionbase64EncodeUnicode(str){utf8Bytes=decodeURIComponent(str).replace(/%([0-9A-F]{2})/g,function(match,p1){returnString.fromCharCode('0x'+p1);});返回atob(utf8Bytes);}getFileSHA()为了更好的理解上面的代码,我创建了四个变量来存储不同状态的数据让fileSHA,fileBlob,fileContent,filefileSHA用来存储我们要获取的文件的SHA,fileBlob存储从中获取的blobAPI。fileContent用于存储解码后的字符串。文件包含我们实际需要的数据。您可以在下一节中找到相应的参考代码,只需将文件夹路径更改为实际文件路径(带文件扩展名)即可。获取大文件但是,如果您需要获取大于1MB的文件,API将抛出错误。这是因为上面的方法不支持大文件。要获取大文件,我们不得不改用GithubAPI。这种类型的API允许您从Git存储库和列表中读取和写入原始Git对象,以及更新Git引用。这类API主要适用于blob,这是本文的重点。Git将大文件转换为base64编码的blob,而不是存储整个文件以获得更好的性能。所以当你请求同一个文件时,你应该使用返回blob的接口。要获取blob,需要传递文件对应的SHA。您可能想知道,什么是SHA?以及如何获得它?每次提交新文件时,git都会创建一个称为散列或SHA的唯一ID来记录更改。但有时它会导致问题,我将在本文末尾讨论。获取文件对应的SHA现在,我们需要想办法获取所需文件的“SHA”。GitHubAPI有一个接口,可用于与我们需要处理的文件内容进行交互。GET/repos/{owner}/{repo}/contents/{path}作为响应,我们得到一个包含目录中每个文件元数据的相关对象数组。元数据包含我们可以稍后存储和使用的SHA。constgetFileSHA=async()=>{try{constresponse=awaitfetch("");constdata=awaitresponse.json();控制台日志(数据);fileSHA=data[3].shaconsole.log(fileSHA);}赶上(错误){console.log(错误);}getFileBlob(fileSHA)}data[3].sha是与votes_by_region.json的SHA,所以我们将其存储在fileSHA中以备后用。下图是控制台的输出:Getthecorrespondingblob我们已经获得了blob需要的SHA。我们需要使用不同的接口来处理blob。该接口与上一个接口类似,但是该接口需要将文件对应的SHA作为第三个参数传递。GET/repos/{owner}/{repo}/git/blobs/{file_sha}当我们将文件的SHA作为参数提供给下面的函数时,我们可以得到相应的blob。constgetFileBlob=async(fileSHA)=>{try{constresponse=awaitfetch(`https://api.github.com/repos/hackernoon/where-startups-trend/git/blobs/${fileSHA}`);constdata=awaitresponse.json();fileBlob=data.contentconvertBlob(fileBlob)}catch(error){console.log(error);}}这个请求返回一个base64编码的blob。Base64是一种以ASCII字符串格式表示二进制数据的编码方案。当我们需要不做任何修改地存储或传输数据时,它很有用。控制台输出看起来很乱,但这就是base64编码数据的工作原理。将blob转换为可用数据最后一步,我们需要将base64编码的blob转换为我们可以在程序中使用的数据。但是这一步非常令人沮丧,因为标准方法在某些情况下似乎不起作用。在这个问题上花了几个小时后,我找到了三个解决方案。1.最简单的方式这是JavaScript原生支持的标准方式。atob()是一个WebAPI接口,可将base64编码的数据解码为纯字符串。atob将ASCII转换为二进制读取,因为它将ASCII编码的base64数据转换为二进制形式。输出将是解码后的字符串。要将其转换为其原始数据类型,我们使用JSON.parse()。fileContents=atob(blob)file=JSON.parse(fileContents)2.方法二如果上面的方法抛出错误,可以使用Node.js提供的方法Buffer.from()。它将要解码的字符串作为第一个参数,将编码技术作为第二个参数。try{constfileContents=Buffer.from(fileBlob,"base64").toString()file=JSON.parse(blobToString)console.log(file)}catch(error){console.log(error)}3.第三个如果你在前端工作,上述方法很可能不起作用。在这种情况下,创建一个使用decodeURIComponent的函数。//定义函数constdecodeBase64=str=>{utf8Bytes=decodeURIComponent(str).replace(/%([0-9A-F]{2})/g,function(match,p1){returnString.fromCharCode('0x'+p1);});returnatob(utf8Bytes);}您可以通过将fileBlob作为参数传递来调用此函数,并获取所需的解码字符串。fileContents=decodeBase64(fileBlob)file=JSON.parse(fileContents)console.log(file)仍然不起作用此时,您可以尝试最后两个选项。您可以使用FileReaderAPI或以不同方式使用decodeURIComponent。1.FileReaderAPI:您可以在此处找到MDN文档(https://developer.mozilla.org/en-US/docs/Web/API/FileReader?ref=hackernoon.com)2.decodeURIComponent:请参阅RajeevSingh博客了解如何处理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()函数中有一个硬编码的对象索引,如果您在目录中添加或删除文件,API可能会使用不同文件的SHA进行响应。为了解决这个问题,您可以显式指定文件名而不是索引,这样您就可以在提交新更改后保持函数不变。摘要和TL;DR1。Git以blob格式存储较大的文件,因此我们使用GitHub数据库API来获取大于1MB的文件。2.我们需要提供文件的用户名、repo名称和SHA来获取blob。3.为了获得SHA,我们需要提供接口的文件夹路径并将其存储在变量中。4.之后我们需要将SHA作为参数传递给另一个接口并获得base64编码的blob。5.必须先将blob解码为纯字符串,然后使用JSON.parse()将其转换为原始格式,然后才能使用。更多参考GitHub存储库内容(https://docs.github.com/en/rest/reference/repos?ref=hackernoon.com#contents)Git数据库(https://docs.github.com/en/rest/reference/git?ref=hackernoon.com)Git数据库API入门(https://docs.github.com/en/rest/guides/getting-started-with-the-git-database-api?ref=hackernoon.com)译者介绍社区编辑赵庆尧,从事驱动开发多年。他的研究兴趣包括安全操作系统和网络安全,并发表了与网络相关的专利。原标题:HowtoFetchLargeDataFilesThroughGitHubAPI,作者:KaushalJoshi