如何使用JavaScript结合GitHub API上传图片等非文本文件?
解决JavaScript调用GitHub API上传非文本文件乱码的问题
你的问题核心在于二进制文件的编码处理方式错误——用readAsText或者encodeURIComponent/unescape这套文本处理逻辑去处理二进制数据,会直接破坏原始字节,导致GitHub收到的Base64编码对应的数据已经损坏,自然会出现乱码。
GitHub API要求上传非文本文件时,content字段必须是原始二进制内容直接转换的Base64编码,不能经过任何文本转码步骤。下面是具体的修复方案:
1. 正确读取二进制文件
放弃使用readAsText或readAsDataURL(后者会带data:...前缀,且处理逻辑不适合原始二进制),改用FileReader.readAsArrayBuffer读取文件的原始二进制数据,再将其转换为符合要求的Base64编码。
2. 实现ArrayBuffer到Base64的转换
写一个辅助函数,把ArrayBuffer直接转成纯Base64字符串(不带任何前缀):
function arrayBufferToBase64(buffer) { let binary = ''; const bytes = new Uint8Array(buffer); const len = bytes.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary); }
3. 修改文件读取与上传逻辑
更新你的readURL和createfile函数,适配二进制文件处理:
修改后的readURL函数
function readURL(input) { if (input.files && input.files[0]) { const file = input.files[0]; const reader = new FileReader(); reader.onload = function(e) { // 将ArrayBuffer转成纯Base64编码 const base64Content = arrayBufferToBase64(e.target.result); // 调用上传函数 createfile(file.name, "uploading binary file", base64Content); }; // 不管什么类型的文件,都用readAsArrayBuffer读取原始二进制 reader.readAsArrayBuffer(file); } }
修改后的createfile函数
移除多余的编码步骤,直接使用传入的Base64内容:
function createfile(fileName, fileMessage, base64Content) { const apiUrl = `https://api.github.com/repos/el3zahaby/testet/contents/${encodeURIComponent(fileName)}`; const fileData = JSON.stringify({ message: fileMessage, content: base64Content }); $.ajax({ url: apiUrl, type: 'PUT', beforeSend: function(xhr) { // 注意:生产环境不要硬编码用户名密码,建议用GitHub Personal Access Token // 格式改为 "token YOUR_TOKEN" xhr.setRequestHeader("Authorization", "Basic " + btoa("USERNAME:PASSWORD")); }, data: fileData, contentType: 'application/json' // 明确指定Content-Type }).done(function(response) { console.log("文件上传成功:", response); }).fail(function(error) { console.error("上传失败:", error); }); }
关键注意事项
- 不要用文本处理逻辑处理二进制:
readAsText会把二进制数据当成UTF-8文本解析,很多字节不是有效的UTF-8字符,会被替换成乱码;encodeURIComponent/unescape这套是用来处理URL编码的文本,完全不适合二进制。 - GitHub API的Content字段要求:必须是原始二进制的Base64编码,不能带
data:image/png;base64,这类前缀。 - 安全提示:硬编码用户名密码在前端代码里非常不安全,建议改用GitHub Personal Access Token,请求头改为
Authorization: token YOUR_TOKEN,权限只开repo即可。
这样修改后,不管是图片、视频还是其他二进制文件,都能正确上传到GitHub仓库了。
内容的提问来源于stack exchange,提问作者zahaby




