开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情
什么是 SDK?
SDK(Software Development Kit)即 软件开发工具包 ,就是帮助我们开发出软件的工具集合,除了代码之外,一般还要搭配文档、示例等。
除了 SDK
以外还有 JDK(Java Development Kit)
,前缀不重要,重要的是 DK(Development Kit)
,就是开发工具包,对于前端来说 SDK
就是 npm
包,某个有专门功能的包,但是 SDK
的概念要早于 npm
包,而且 JS SDK
一般都会当 npm
包部署
与 npm 包的区别
非要说两者有什么区别的话,就是 SDK
是提供方的一种服务,通常是封装了提供方的 Open API
,然后 SDK
通过暴露 JS API
给外部用户使用,比如七牛云提供的 qiniu/js-sdk 里面就包含七牛云存储官方 API
PS: 有关讨论
适用场景
一个应用的JS-SDK大概可以分为以下三种
- 分析与统计工具(类似百度统计的js-sdk工具)
- 嵌入式类(类似 widget、视频播放器(video)的 sdk)
- Web的API集合(类似微信官方的js-sdk工具)
使用
这里还是用七牛云提供的 qiniu/js-sdk 做示范
import * as qiniu from 'qiniu-js'
const observable = qiniu.upload(file, key, token, putExtra, config)
const subscription = observable.subscribe(observer) // 上传开始
// or
const subscription = observable.subscribe(next, error, complete) // 这样传参形式也可以
subscription.unsubscribe() // 上传取消
就是和 npm
包的使用一致,没啥大的区别
本来想用微博的 sdk 包的,但没想到又要审核!
手写 JS SDK
国内很多提供第三方登录的服务商,比如微博,提供给网站的是 SDK
,而 github
的 OAuth
就是纯 API
或者纯接口,而这次手写的 JS SDK
就是给 github
的登录时自动加上 state
(一个 github
防 csrf
攻击的参数)
你可以在线查看所有的源代码
SDK
在设计要求以下
- 最小可用性原则: 也就是没有必要的功能/代码尽量不额外添加, 使代码达到最简
- 最少依赖原则: 也就是没有必要的依赖坚决不添加, 以达到最低限度的外部依赖
- 易扩展: 插件化,最大限度支持扩展和自定义
- 稳定性: 绝不能导致宿主应用崩溃,向后兼容, 可测试
关于 GitHub
的第三方登录可以查看这篇文章
Github
是跳转登录,其 url
如下
GET https://github.com/login/oauth/authorize
参数
其中 state
是作为防止 csrf
攻击存在的,但是关于它的处理上为了让开发不去过于纠结,所以可以单独抽取出来,这就是我们设计的 SDK
的基本逻辑,如下
const md5 = require("blueimp-md5");
const login = async ({ client_id, redirect_uri }) => {
const timestamp = new Date().getTime();
const state = md5(timestamp);
localStorage.setItem("state", state);
window.location.href = `https://github.com/login/oauth/authorize?client_id=${client_id}&redirect_uri=${redirect_uri}&state=${state}`;
};
顺便给 state 加上一个 md5
然后重定向之后的操作也由我们的 SDK
完成
const checkLogin = (callback) => {
/**
* 获取URL参数
* @param 参数名
*/
function getQueryString(name) {
const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
const r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURI(r[2]);
return null;
}
function getLocalState() {
return localStorage.getItem("state");
}
const code = getQueryString("code");
const state = getQueryString("state");
if (code && state === getLocalState()) {
callback(code);
}
};
然后使用上就可以调用这两个 API
const GithubSDK = require("../../csrf-github-oauth-sdk/index.js");
// redirect_uri 处页面执行检测
GithubSDK.checkLogin((code) => {
// 成功后获取 token
// ...
});
// ...
window.handleGithubLoginClick = () => {
GithubSDK.login({
client_id: "b351931efd1203b2230e",
redirect_uri: "http://localhost:8080/login.html",
});
}
从导入来说和正常 npm
包一致,但是又和平常的业务代码不同,因为并不需要我们自己去写 Ajax
,而是封装在了我们开发的 SDK
中