SDK 是什么?和 npm 包有什么区别?简单写个例子了解 JS SDK

4,743 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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,而 githubOAuth 就是纯 API 或者纯接口,而这次手写的 JS SDK 就是给 github 的登录时自动加上 state(一个 githubcsrf 攻击的参数)

你可以在线查看所有的源代码

SDK 在设计要求以下

  • 最小可用性原则: 也就是没有必要的功能/代码尽量不额外添加, 使代码达到最简
  • 最少依赖原则: 也就是没有必要的依赖坚决不添加, 以达到最低限度的外部依赖
  • 易扩展: 插件化,最大限度支持扩展和自定义
  • 稳定性: 绝不能导致宿主应用崩溃,向后兼容, 可测试

关于 GitHub 的第三方登录可以查看这篇文章

Github 是跳转登录,其 url 如下

GET https://github.com/login/oauth/authorize

参数

  1. client_id - string - “必需”。 注册时从 GitHub 收到的客户端 ID。
  2. redirect_uri - string - 用户获得授权后被发送到的应用程序中的 URL。 请参阅以下有关重定向 URL 的详细信息。
  3. state - string - 不可猜测的随机字符串。 它用于防止跨站请求伪造攻击。

其中 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

参考资料

  1. 对于前端而言,jssdk 和 npm 包有啥区别呢? - 知乎
  2. 前端JS-SDK那些事 - 掘金 - 树酱