越努力,越幸运!
平时用来提交代码的仓库,经过一番小折腾,眨眼就变成了个白嫖图床。居然可以这么玩,不要太给力。刚开始可能难以理解,毕竟关于github接触最多的还是git命令行。事实上,这也很容易实现。
github图床介绍
github图床实质上还是一个仓库,它和普通仓库就在于操作方式的不同。一个普通仓库,我们是采用git命令来管理的;github图床的文件操作则完全是通过远程Api,以调接口的形式来管理。github为开发者提供了额外的Api支持,要搭建一个图床,我们仅需要一个仓库-新建文件的api。
github RestApi
接口鉴权
github就是一台远程服务器,它提供了一个上传文件的接口。在调用它之前需要我们进行一下接口验证。
- Basic authentication
在调用接口的时候,传入(github)用户名和密码参数。这种是最直接的方法,但它有很多弊端。一方面会暴露用户信息,不太安全;另一方面,这种方式的调用次数有限制(每小时不超过60次)。 - OAuth2 token(推荐)
调用时,在请求头里附上Authorization: token OAUTH-TOKEN。这种方式较安全也没有次数限制,不过它需要我们申请一个token。
接口参数
- 接口基地址: https://api.github.com
- 接口类型&接口地址:
Put /repos/{owner}/{repo}/contents/{path}
- 接口参数
参数 描述 owner github用户名 repo 图床仓库名 path 写入的文件路径,它会创建不存在的目录 message github仓库提交信息(瞎写就行) content 文件的base64编码格式
图片访问
调用上传接口,如果返回状态码是201,说明上传成功。那该怎么访问图片呢?
GitHub Pages
打开图床仓库的设置菜单,找到GitHub Pages选项并开启。开启之后会得到一个地址,用这个地址拼接刚刚上传的文件路径,就可以访问了。
jsdelivr
jsdelivr是一个免费的CDN服务,而且它本来也支持github资源。不仅不用申请账号,而且使用时只需要替换下以链接: https://cdn.jsdelivr.net/gh/userepo@version/file
。
vue调用实例
<template>
<div style="margin: 50px">
<el-upload
class="avatar-uploader"
action=""
:show-file-list="false"
:before-upload="beforeAvatarUpload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
</template>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
<script>
export default {
data() {
return {
imageUrl: "",
};
},
methods: {
beforeAvatarUpload(file) {
const isJPG = file.type.indexOf("image") != -1;
const isLt2M = file.size / 1024 / 1024 < 10;
if (!isJPG) {
this.$message.error("上传的图片 格式错误!");
}
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 10MB!");
}
this.getBase64(file).then((base64File) => {
const fileStr = base64File.slice(base64File.indexOf(",") + 1);
const filePath = new Date().toLocaleDateString().replace(/\//g, "") + "/" + file.name;
this.$http.put("https://api.github.com/repos/Dany-neo/picture/contents/" + filePath, {
message: "upload img",
content: fileStr,
})
.then((res) => {
// 开始GitHub Pages服务,访问图床
this.imageUrl = "https://dany-neo.github.io/picture/" + filePath;
// 使用jsdelivr访问
this.imageUrl = 'https://cdn.jsdelivr.net/gh/Dany-neo/picture@master/' + filePath
});
});
return false;
},
/**
* @param file
* @return base64
* */
getBase64(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
let fileResult = "";
reader.readAsDataURL(file);
//开始转
reader.onload = function () {
fileResult = reader.result;
};
//转 失败
reader.onerror = function (error) {
reject(error);
};
//转 结束 咱就 resolve 出去
reader.onloadend = function () {
resolve(fileResult);
};
});
},
},
};
</script>
踩过的坑
- token的值只会显示一次,如果错过了没有复制的话,还得删掉重来
- Authorization字段值是: token空格+用户token值
- 接口所需的base64字符,需要删掉 第一个逗号之前的部分
- 有时候调用会很慢,一个是因为github网速,一个是因为浏览器生成base64速度慢