最近基于 Github API 开发了一款图床 Chrome 插件 Picee,如今已经开源并上架 Chrome 应用商店。当中的过程涉及到一些有趣的知识点,故将其记录下来。javascript
Github地址: https://github.com/jrainlau/p...Chrome商店下载地址:Piceecss
平时有写点东西的习惯,可是奈何一直找不到合适的图床。有人推荐以微博或者七牛来作图床,可是总给我一种”受制于人“的感受,不知道何时就会被各类限制,好比禁止图片外链等等。后来发现其实 Github 是很是适合作图床的,由于仓库里的文件均可以经过 https://raw.githubusercontent.com
这个连接直接外链以供下载。可是若是为了写个文章而每次添加图片都须要一顿 Git 操做,那么写做体验一定很是很差,若是有更方便的办法就行了——那就是Github API。html
Github 提供了一套完善的 API 以供操做,几乎涵盖了开发一个完整 Github 客户端的全部功能。API 分为 REST 风格的 v3 版本和 GraphQL 风格的 v4 版本。为了使用方便,我选择的是 v3 版本。具体的 API 细节能够在官方文档查看。vue
要制做一个图床应用,咱们只须要用到上传文件的 API 便可。可是在调用这个 API 以前,首选须要用户对应用进行受权,也就是所谓的登陆操做。java
对于通常的”查看”操做,是不须要受权的,好比获取用户的公开信息,获取公有仓库的 issues 等等。可是有两个场景是须要受权的,其一是任何对于仓库的“增删改查”操做(包括提交 issue,评论等);其二则是对于某 IP 有 API 的调用次数限制,若这个 IP 调用 Github API 的次数过多则须要受权。git
那么受权应该怎么作呢?官方提供了三种办法,分别是 Basic
,oAuth2 token
和oAuth2 key/secret
。github
也就是最传统的帐号密码受权方式,咱们能够在命令行用 curl
来测试之:web
curl -u "帐号:密码" https://api.github.com
若是是正确的帐号密码,则会返回一系列的内容,不然会返回错误信息。chrome
对于开发来讲,我更推荐使用 Postman 来对 API 进行测试:json
点开右边的 code ,能够看到 JS 代码:
其中 xhr.setRequestHeader("Authorization", "Basic xxxxxx");
就是咱们须要设置的受权 header,当中的 xxxxxx
是这么来的:
btoa(username + ':' + password)
对于帐号密码来讲,轻易地在第三方平台输入其实并不那么安全,那么有没有办法既能保障帐户的安全,又能实现受权的需求呢?答案就是 oAuth token。
简单来讲,oAuth token 至关于用户提供给第三方的一张受权令牌,第三方经过这张令牌能够得到用户所容许使用的一系列权限,可是却不会知晓用户的帐号和密码,因而便得以在有效保障用户帐号安全的同时,又能方便地对第三方应用进行受权。
在 Github 里,能够在这个地方设置生成具备某些权限的 token:
最后在 Postman 里选择 OAuth 2.0 或者 Bearer Token,而后把这串 token 粘贴进去便可。
其中的受权 header 为 Bearer token
。
这种受权方式是经过生成一对 key/secret,来容许第三方获取用户的公开信息,是一种只读的受权方式,没法对仓库进行改写操做,主要用于第三方登陆,故在这里不适用。更多关于 key/secret 的内容能够查看阮一峰的《GitHub OAuth 第三方登陆示例教程》,写得很是生动详细。
在了解了三种受权方式以后,咱们就能够进行下一步操做,实现图片的上传了。
图片上传使用了 content API 的 create-a-file 接口,经过 PUT 发送一条文件内容为 base64 的请求到指定的仓库目录。
这里着重圈出了必须把文件进行 base64 编码,不然接口调用将会出错。
经过 btoa('hello world)
方法把 hello world
转成 base64,而后放在 Postman 里测试一下:
看来效果是OK的,接下来就是对图床插件进行开发的步骤了。
除了看官方文档学习插件开发之外,也能够参考由@小茗同窗 所写的《【干货】Chrome插件(扩展)开发全攻略》,里面对于 Chrome 插件的开发有着详细的叙述,很是值得一读。
读完上面推荐的文章以后,我选择使用 VueJS 进行开发。因为项目比较简单,因此我没有用任何的打包工具,直接经过 script 的方式引入 VueJS。值得注意的是,Chrome 插件不容许行内 script 和行内 style,因此任何的 css 和 js 文件都必须经过本地文件连接的方式去使用。另外因为咱们的 JS 是运行在 Chrome 环境的,因此能够放心大胆地使用 es 模块和 async/await 等高级语法,而无需任何的构建工具参与。
可是在使用 VueJS 的第一步我就遇到了问题,绑定了 new Vue()
的 DOM 元素居然显示不出来。通过查证,原来 Chrome 插件有 Content Security Policy (CSP) 限制,默认是不支持 eval()
,new Function()
等方式运行代码的,而完整版的 VueJS 刚好是这么干的(官网有说),因此就出问题了。那么怎么解决呢?很简单,在 manifest.json
里面声明一下就行了:
// manifest.json { // ... "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'" }
这里我采用的是 popup 形式的插件,弹出来的窗口就是项目所定义的 index.html。若是要调试插件的页面,能够直接在插件弹出的窗口点击右键,而后点击“检查”,就会弹出咱们熟悉的开发者工具了。若是插件文件有改动,除了从新打开插件之外,咱们也能够在开发者工具经过 cmd + r
去直接刷新,省去了屡次点击的麻烦。
通过前面的准备,咱们已经掌握了如何对 Github API 进行受权而后上传图片的办法,接下来就是在业务逻辑里去实现它们。我封装了一下原生的 fetch 方法,让它更方便调用:
const $fetch = (options) => { return window.fetch(options.url, { method: options.method || 'GET', headers: { "Content-Type": "application/json", "Authorization": localStorage.getItem('picee_token') }, body: JSON.stringify(options.body) || null, mode: 'cors' }) .then(async res => { if (res.status >= 200 && res.status < 400) { return { status: res.status, data: await res.json() } } else { return { status: res.status, data: null } } }) .catch(e => e) } export default $fetch
请求接口时携带的受权 header 所需的 token,我把它们存放在插件的 localStorage 下,方便调用。
有了请求接口的方法之后,接下来就要完成选择图片和把图片转化成 base64 的工做。这里我复用了另外一个做品里的 chooseImg.js
和 paste.js
方法,最终可以支持以选择、粘贴、拖拽的方式上传图片。
剩下的一些功能细节就不赘述了,代码很是简单,建议读者们自行查阅。
准备好了 logo,描述等善后工做以后,就能够正式提交应用发布了。咱们能够在开发者信息中心里面把插件提交上去,填入必要的信息之后点击发布,等待审核完成。可是在此以前,你必须支付5美圆的开发者注册费,国内的开发者在完成这一步的时候可能会遇到蛮大的困难,这一个问题在知乎也有讨论:如何在中国使用信用卡支付“Chrome 网上应用店”开发者注册费?。我是经过万能的淘宝搞定的。
在完成注册以后和发布之后,就能看到插件的主页了:
值得注意的是,刚发布的插件是暂时不能被搜索出来的,须要等待一段时间之后才能搜索出来。
至此,整个插件的开发——发布流程就已经完成了。