Skip to content

Commit 2a1d9fc

Browse files
committed
实现优化
1 parent 99f179d commit 2a1d9fc

File tree

17 files changed

+223
-198
lines changed

17 files changed

+223
-198
lines changed

README.md

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
### 当前版本为 3.x,旧版本文档:[2.x](https://github.com/qiniu/js-sdk/tree/2.x)[1.x](https://github.com/qiniu/js-sdk/tree/1.x)
1010

11-
### 2.x 升级到 3.x 的注意事项请参考[文档](https://github.com/qiniu/js-sdk/wiki/2.x-%E5%8D%87%E7%BA%A7%E5%88%B0-3.x-%E6%96%87%E6%A1%A3%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9)
11+
### 2.x 升级到 3.x 的注意事项请参考 [文档](https://github.com/qiniu/js-sdk/wiki/2.x-%E5%8D%87%E7%BA%A7%E5%88%B0-3.x-%E6%96%87%E6%A1%A3%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9)
1212

1313
## 快速导航
1414

@@ -38,7 +38,7 @@ Qiniu-JavaScript-SDK 为客户端 SDK,没有包含 `token` 生成实现,为
3838
* [C/C++](https://developer.qiniu.com/kodo/sdk/cpp)
3939
* [Objective-C](https://developer.qiniu.com/kodo/sdk/objc)
4040

41-
Qiniu-JavaScript-SDK 的示例 [Demo](http://jssdk-v2.demo.qiniu.io) 中的服务器端部分是基于[Node.js 服务器端 SDK](https://developer.qiniu.com/kodo/sdk/nodejs) 开发的。
41+
Qiniu-JavaScript-SDK 的示例 [Demo](http://jssdk-v2.demo.qiniu.io) 中的服务器端部分是基于 [Node.js 服务器端 SDK](https://developer.qiniu.com/kodo/sdk/nodejs) 开发的。
4242

4343
* [JavaScript SDK 在线示例](http://jssdk-v2.demo.qiniu.io/)
4444

@@ -64,12 +64,12 @@ Qiniu-JavaScript-SDK 的示例 [Demo](http://jssdk-v2.demo.qiniu.io) 中的服
6464

6565
## 准备
6666

67-
* 在使用 JS-SDK 之前,您必须先注册一个七牛帐号,并登录控制台获取一对有效的 `AccessKey``SecretKey`,您可以阅读[快速入门](https://developer.qiniu.com/kodo/manual/console-quickstart)[安全机制](https://developer.qiniu.com/kodo/manual/security#security) 以进一步了解如何正确使用和管理密钥 。
67+
* 在使用 JS-SDK 之前,您必须先注册一个七牛帐号,并登录控制台获取一对有效的 `AccessKey``SecretKey`,您可以阅读 [快速入门](https://developer.qiniu.com/kodo/manual/console-quickstart)[安全机制](https://developer.qiniu.com/kodo/manual/security#security) 以进一步了解如何正确使用和管理密钥 。
6868

6969
* JS-SDK 依赖服务端颁发 `token`,可以通过以下二种方式实现:
7070

71-
* 利用[七牛服务端 SDK](https://developer.qiniu.com/sdk#sdk)构建后端服务
72-
* 利用七牛底层 API 构建服务,详见七牛[上传策略](https://developer.qiniu.com/kodo/manual/put-policy)[上传凭证](https://developer.qiniu.com/kodo/manual/upload-token)
71+
* 利用 [七牛服务端 SDK](https://developer.qiniu.com/sdk#sdk) 构建后端服务
72+
* 利用七牛底层 API 构建服务,详见七牛 [上传策略](https://developer.qiniu.com/kodo/manual/put-policy)[上传凭证](https://developer.qiniu.com/kodo/manual/upload-token)
7373

7474
前端通过接口请求以获得 `token` 信息
7575

@@ -89,7 +89,7 @@ Qiniu-JavaScript-SDK 的示例 [Demo](http://jssdk-v2.demo.qiniu.io) 中的服
8989

9090
* 使用 NPM 安装
9191

92-
NPM 的全称是 Node Package Manager,是一个[NodeJS](https://nodejs.org)包管理和分发工具,已经成为了非官方的发布 Node 模块(包)的标准。如果需要更详细的关于 NPM 的使用说明,您可以访问[NPM 官方网站](https://www.npmjs.com),或对应的[中文网站](http://www.npmjs.com.cn/)
92+
NPM 的全称是 Node Package Manager,是一个 [NodeJS](https://nodejs.org) 包管理和分发工具,已经成为了非官方的发布 Node 模块(包)的标准。如果需要更详细的关于 NPM 的使用说明,您可以访问 [NPM 官方网站](https://www.npmjs.com),或对应的 [中文网站](http://www.npmjs.com.cn/)
9393

9494
```
9595
npm install qiniu-js
@@ -173,12 +173,13 @@ qiniu.compressImage(file, options).then(data => {
173173
* total.total: `number`,本次上传的总量控制信息,单位为字节,注意这里的 total 跟文件大小并不一致。
174174
* total.percent: `number`,当前上传进度,范围:0100
175175

176-
* error: 上传错误后触发;自动重试本身并不会触发该错误,而当重试次数到达上限后则可以触发。当不是 xhr 请求错误时,会把当前错误产生原因直接抛出,诸如 JSON 解析异常等;当产生 xhr 请求错误时,参数 err 的类型为 `QiniuError`, 你可以通过 `error.type` 得知具体的错误类型,通过 `error.message` 获取错误的信息,对于请求错误,err 的类型为 `QiniuRequestError`(继承自`QiniuError`)。
176+
* error: 上传错误后触发;自动重试本身并不会触发该错误,而当重试次数到达上限后则可以触发。当不是 xhr 请求错误时,会把当前错误产生原因直接抛出,诸如 JSON 解析异常等;当产生 xhr 请求错误时,参数 err 的类型为 `QiniuError`, 你可以通过 `error.name` 得知具体的错误类型,通过 `error.message` 获取错误的信息,对于请求错误,err 的类型为 `QiniuRequestError`(继承自`QiniuError`)。
177177
* `QiniuRequestError` 拥有额外的信息:
178178
* err.reqId: `string`,xhr 请求错误的 `X-Reqid`
179-
* err.code: `number`,请求错误状态码,可查阅码值对应[说明](https://developer.qiniu.com/kodo/api/3928/error-responses)。
179+
* err.code: `number`,请求错误状态码,可查阅码值对应 [说明](https://developer.qiniu.com/kodo/api/3928/error-responses)。
180+
* err.isRequestError: 用于区分是否为 xhr 请求错误;当 xhr 请求出现错误并且后端通过 HTTP 状态码返回了错误信息时,该参数为 `true`;否则为 `undefined`
180181

181-
* complete: 接收上传完成后的后端返回信息,具体返回结构取决于后端sdk的配置,可参考[上传策略](https://developer.qiniu.com/kodo/manual/1206/put-policy)。
182+
* complete: 接收上传完成后的后端返回信息,具体返回结构取决于后端sdk的配置,可参考 [上传策略](https://developer.qiniu.com/kodo/manual/1206/put-policy)。
182183

183184
* subscription: 为一个带有 `unsubscribe` 方法的类实例,通过调用 `subscription.unsubscribe()` 停止当前文件上传。
184185

@@ -197,7 +198,7 @@ qiniu.compressImage(file, options).then(data => {
197198

198199
* config.useCdnDomain: 表示是否使用 cdn 加速域名,为布尔值,`true` 表示使用,默认为 `false`
199200
* config.disableStatisticsReport: 是否禁用日志报告,为布尔值,默认为 `false`
200-
* config.uphost: 上传 `host`,类型为 `string[] | string` 使用 `string[]` 时,内部会在重试过程中自动尝试不同的 `host`,如果设定该参数则优先使用该参数作为上传地址,默认为 `[]`
201+
* config.uphost: 上传 `host`,类型为 `string[] | string`如果设定该参数则优先使用该参数作为上传地址,默认为 `[]`,传入多个 `host` 时,内部会在重试过程中根据情况自动切换不同的 `host`
201202
* config.upprotocol: 自定义上传域名协议,值为 `https` 或者 `http`,默认为 `https`
202203
* config.region: 选择上传域名区域;当为 `null``undefined` 时,自动分析上传域名区域。
203204
* config.retryCount: 上传自动重试次数(整体重试次数,而不是某个分片的重试次数);默认 3 次(即上传失败后最多重试两次)。
@@ -219,7 +220,7 @@ qiniu.compressImage(file, options).then(data => {
219220
```
220221

221222
* fname: `string`,文件原始文件名,若未指定,则魔法变量中无法使用 fname、ext、suffix
222-
* customVars: `object`,用来放置自定义变量,变量名必须以 `x:` 开始,自定义变量格式及说明请参考[文档](https://developer.qiniu.com/kodo/manual/1235/vars)
223+
* customVars: `object`,用来放置自定义变量,变量名必须以 `x:` 开始,自定义变量格式及说明请参考 [文档](https://developer.qiniu.com/kodo/manual/1235/vars)
223224
* metadata: `object`,用来防止自定义 meta,变量名必须以 `x-qn-meta-`开始,自定义资源信息格式及说明请参考
224225
[文档](https://developer.qiniu.com/kodo/api/1252/chgm)
225226
* mimeType: `string`,指定所传的文件类型
@@ -292,7 +293,7 @@ qiniu.compressImage(file, options).then(data => {
292293
mode: 1, // 图片水印
293294
image: 'http://www.b1.qiniudn.com/images/logo-2.png', // 图片水印的Url,mode = 1 时 **必需**
294295
dissolve: 50, // 透明度,取值范围1-100,非必需,下同
295-
gravity: 'SouthWest', // 水印位置,为以下参数[NorthWest、North、NorthEast、West、Center、East、SouthWest、South、SouthEast]之一
296+
gravity: 'SouthWest', // 水印位置,为以下参数 [NorthWest、North、NorthEast、West、Center、East、SouthWest、South、SouthEast] 之一
296297
dx: 100, // 横轴边距,单位:像素(px)
297298
dy: 100 // 纵轴边距,单位:像素(px)
298299
}, key, domain)
@@ -318,23 +319,23 @@ qiniu.compressImage(file, options).then(data => {
318319
}, key, domain)
319320
```
320321

321-
options包含的具体水印参数解释见[水印(watermark)](https://developer.qiniu.com/dora/api/image-watermarking-processing-watermark)
322+
options包含的具体水印参数解释见 [水印(watermark)](https://developer.qiniu.com/dora/api/image-watermarking-processing-watermark)
322323

323324
### qiniu.imageView2(options: object, key?: string, domain?: string): string (缩略)
324325

325326
返回处理后的图片url
326327

327328
```JavaScript
328329
const imgLink = qiniu.imageView2({
329-
mode: 3, // 缩略模式,共6种[0-5]
330+
mode: 3, // 缩略模式,共 6 种 [0-5]
330331
w: 100, // 具体含义由缩略模式决定
331332
h: 100, // 具体含义由缩略模式决定
332333
q: 100, // 新图的图像质量,取值范围:1-100
333-
format: 'png' // 新图的输出格式,取值范围:jpg,gif,png,webp等
334+
format: 'png' // 新图的输出格式,取值范围:jpg,gif,png,webp 等
334335
}, key, domain)
335336
```
336337

337-
options包含的具体缩略参数解释见[图片基本处理(imageView2)](https://developer.qiniu.com/dora/api/basic-processing-images-imageview2)
338+
options包含的具体缩略参数解释见 [图片基本处理(imageView2)](https://developer.qiniu.com/dora/api/basic-processing-images-imageview2)
338339

339340
### qiniu.imageMogr2(options: object, key?: string, domain?: string): string (图像高级处理)
340341

@@ -354,23 +355,23 @@ qiniu.compressImage(file, options).then(data => {
354355
}, key, domain)
355356
```
356357

357-
options包含的具体高级图像处理参数解释见[图像高级处理(imageMogr2)](https://developer.qiniu.com/dora/api/the-advanced-treatment-of-images-imagemogr2)
358+
options包含的具体高级图像处理参数解释见 [图像高级处理(imageMogr2)](https://developer.qiniu.com/dora/api/the-advanced-treatment-of-images-imagemogr2)
358359

359360
### qiniu.imageInfo(key: string, domain: string): Promise
360361

361362
```JavaScript
362363
qiniu.imageInfo(key, domain).then(res => {})
363364
```
364365

365-
具体 imageInfo 解释见[图片基本信息(imageInfo)](https://developer.qiniu.com/dora/api/pictures-basic-information-imageinfo)
366+
具体 imageInfo 解释见 [图片基本信息(imageInfo)](https://developer.qiniu.com/dora/api/pictures-basic-information-imageinfo)
366367

367368
### qiniu.exif(key: string, domain: string): Promise
368369

369370
```JavaScript
370371
qiniu.exif(key, domain).then(res => {})
371372
```
372373

373-
具体 exif 解释见[图片 EXIF 信息(exif)](https://developer.qiniu.com/dora/api/photo-exif-information-exif)
374+
具体 exif 解释见 [图片 EXIF 信息(exif)](https://developer.qiniu.com/dora/api/photo-exif-information-exif)
374375

375376
### qiniu.pipeline(fopArr: array, key?: string, domain?: string): string
376377

@@ -435,7 +436,7 @@ qiniu.compressImage(file, options).then(data => {
435436
const imgLink = qiniu.pipeline(fopArr, key, domain))
436437
```
437438

438-
fopArr包含的具体管道操作解释见[管道操作](https://developer.qiniu.com/dora/manual/processing-mechanism)
439+
fopArr包含的具体管道操作解释见 [管道操作](https://developer.qiniu.com/dora/manual/processing-mechanism)
439440

440441
<a id="demo"></a>
441442

@@ -467,7 +468,7 @@ qiniu.compressImage(file, options).then(data => {
467468

468469
2. 如果您想了解更多七牛的图片处理,建议您仔细阅读 [七牛官方文档-图片处理](https://developer.qiniu.com/dora/api/image-processing-api)
469470

470-
3. JS-SDK 示例生成 `token` 时,指定的 `Bucket Name` 为公开空间,所以可以公开访问上传成功后的资源。若您生成 `token` 时,指定的 `Bucket Name` 为私有空间,那您还需要在服务端进行额外的处理才能访问您上传的资源。具体参见[下载凭证](https://developer.qiniu.com/kodo/manual/download-token)。JS-SDK 数据处理部分功能不适用于私有空间。
471+
3. JS-SDK 示例生成 `token` 时,指定的 `Bucket Name` 为公开空间,所以可以公开访问上传成功后的资源。若您生成 `token` 时,指定的 `Bucket Name` 为私有空间,那您还需要在服务端进行额外的处理才能访问您上传的资源。具体参见 [下载凭证](https://developer.qiniu.com/kodo/manual/download-token)。JS-SDK 数据处理部分功能不适用于私有空间。
471472

472473
<a id="faq"></a>
473474

src/api/index.mock.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ import { QiniuRequestError } from '../errors'
22
import * as api from '.'
33

44
export const errorMap = {
5-
invalidRequest: new QiniuRequestError(0, 'mock'), // 请求错误
5+
networkError: new QiniuRequestError(0, 'mock', 'message'), // 网络错误
66

7-
invalidParams: new QiniuRequestError(400, 'mock'), // 无效的参数
8-
expiredToken: new QiniuRequestError(401, 'mock'), // token 过期
7+
invalidParams: new QiniuRequestError(400, 'mock', 'message'), // 无效的参数
8+
expiredToken: new QiniuRequestError(401, 'mock', 'message'), // token 过期
99

10-
gatewayUnavailable: new QiniuRequestError(502, 'mock'), // 网关不可用
11-
serviceUnavailable: new QiniuRequestError(503, 'mock'), // 服务不可用
12-
serviceTimeout: new QiniuRequestError(504, 'mock'), // 服务超时
13-
serviceError: new QiniuRequestError(599, 'mock'), // 服务错误
10+
gatewayUnavailable: new QiniuRequestError(502, 'mock', 'message'), // 网关不可用
11+
serviceUnavailable: new QiniuRequestError(503, 'mock', 'message'), // 服务不可用
12+
serviceTimeout: new QiniuRequestError(504, 'mock', 'message'), // 服务超时
13+
serviceError: new QiniuRequestError(599, 'mock', 'message'), // 服务错误
1414

15-
invalidUploadId: new QiniuRequestError(612, 'mock'), // 无效的 upload id
15+
invalidUploadId: new QiniuRequestError(612, 'mock', 'message'), // 无效的 upload id
1616
}
1717

1818
export type ApiName =

src/api/index.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { region } from '../config'
44
import { getUploadUrl } from '.'
55

66
jest.mock('../utils', () => ({
7+
...jest.requireActual('../utils') as any,
8+
79
request: () => Promise.resolve({
810
data: {
911
up: {
@@ -51,6 +53,15 @@ describe('api function test', () => {
5153
url = await getUploadUrl(config, token)
5254
expect(url).toBe('http://upload.qiniup.com')
5355

56+
config.upprotocol = 'https:'
57+
url = await getUploadUrl(config, token)
58+
expect(url).toBe('https://upload.qiniup.com')
59+
60+
config.upprotocol = 'http:'
61+
url = await getUploadUrl(config, token)
62+
expect(url).toBe('http://upload.qiniup.com')
63+
64+
5465
config.uphost = 'qiniu.com'
5566
url = await getUploadUrl(config, token)
5667
expect(url).toBe('http://qiniu.com')

src/api/index.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { stringify } from 'querystring'
22

3+
import { normalizeUploadConfig } from '../utils'
34
import { Config, UploadInfo } from '../upload'
45
import { regionUphostMap } from '../config'
56
import * as utils from '../utils'
@@ -157,16 +158,13 @@ export function direct(
157158
* @param {string} token
158159
* @returns Promise
159160
* @description 获取上传 url
160-
* @deprecated 将会在下一个大版本中移除
161161
*/
162-
export async function getUploadUrl(config: UploadUrlConfig, token: string): Promise<string> {
163-
const protocol = config.upprotocol || 'https'
162+
export async function getUploadUrl(_config: UploadUrlConfig, token: string): Promise<string> {
163+
const config = normalizeUploadConfig(_config)
164+
const protocol = config.upprotocol
164165

165-
if (config.uphost) {
166-
if (Array.isArray(config.uphost)) {
167-
return `${protocol}://${config.uphost[0]}`
168-
}
169-
return `${protocol}://${config.uphost}`
166+
if (config.uphost.length > 0) {
167+
return `${protocol}://${config.uphost[0]}`
170168
}
171169

172170
if (config.region) {

src/errors/index.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export enum QiniuErrorType {
1+
export enum QiniuErrorName {
22
// 输入错误
33
InvalidFile = 'InvalidFile',
44
InvalidToken = 'InvalidToken',
@@ -24,27 +24,28 @@ export enum QiniuErrorType {
2424
InvalidProgressEventTarget = 'InvalidProgressEventTarget',
2525

2626
// 请求错误
27-
RequestError = 'RequestError'
28-
}
27+
RequestError = 'RequestError',
2928

30-
export class QiniuError extends Error {
31-
constructor(public type: QiniuErrorType, message?: string) {
32-
super(message)
33-
}
29+
// 网络错误
30+
NetworkError = 'NetworkError'
3431
}
3532

36-
export function isQiniuError(error: any): error is QiniuRequestError {
37-
if (error != null && QiniuErrorType[error.type] != null) return true
38-
return false
33+
export class QiniuError implements Error {
34+
public stack: string | undefined
35+
constructor(public name: QiniuErrorName, public message: string) {
36+
this.stack = new Error().stack
37+
}
3938
}
4039

4140
export class QiniuRequestError extends QiniuError {
42-
constructor(public code: number, public reqId: string, message?: string) {
43-
super(QiniuErrorType.RequestError, message)
44-
}
45-
}
4641

47-
export function isQiniuRequestError(error: any): error is QiniuRequestError {
48-
if (isQiniuError(error) && error.type === QiniuErrorType.RequestError) return true
49-
return false
42+
/**
43+
* @description 标志当前的 error 类型是一个 RequestError
44+
* @deprecated 下一个大版本将会移除
45+
*/
46+
public isRequestError = true
47+
48+
constructor(public code: number, public reqId: string, message: string) {
49+
super(QiniuErrorName.RequestError, message)
50+
}
5051
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
export { imageMogr2, watermark, imageInfo, exif, pipeline } from './image'
2+
export { QiniuErrorName, QiniuError, QiniuRequestError } from './errors'
23
export { deleteUploadedChunks, getUploadUrl } from './api'
34
export { default as upload } from './upload'
45
export { region } from './config'
5-
export * from './errors'
66

77
export {
88
compressImage,

src/logger/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default class Logger {
1717
) { }
1818

1919
private getPrintPrefix(level: LogLevel) {
20-
return `Qiniu-JS-SDK [${level}][${this.prefix}#${this.id}]: `
20+
return `Qiniu-JS-SDK [${level}][${this.prefix}#${this.id}]:`
2121
}
2222

2323
/**

0 commit comments

Comments
 (0)