0
# File Upload
1
2
Core file upload functionality with automatic upload strategy selection, progress tracking, and resume capabilities for large files.
3
4
## Capabilities
5
6
### Upload Function
7
8
Main upload function that automatically selects between direct upload (≤4MB) and resumable chunked upload (>4MB).
9
10
```typescript { .api }
11
/**
12
* Upload a file to Qiniu Cloud Storage
13
* @param file - File object to upload
14
* @param key - Target filename, null for auto-generated key
15
* @param token - Upload token from server
16
* @param putExtra - Optional upload metadata and custom variables
17
* @param config - Optional upload configuration
18
* @returns Observable for tracking upload progress and completion
19
*/
20
function upload(
21
file: File,
22
key: string | null | undefined,
23
token: string,
24
putExtra?: Partial<Extra>,
25
config?: Config
26
): Observable<UploadProgress, QiniuError | QiniuRequestError | QiniuNetworkError, UploadCompleteData>;
27
```
28
29
**Usage Examples:**
30
31
```typescript
32
import { upload, region } from "qiniu-js";
33
34
// Basic upload with minimal configuration
35
const file = document.getElementById('fileInput').files[0];
36
const token = await getTokenFromServer(); // Your server implementation
37
38
const subscription = upload(file, null, token).subscribe({
39
next: (progress) => {
40
console.log(`Upload progress: ${progress.total.percent.toFixed(1)}%`);
41
console.log(`Uploaded: ${progress.total.loaded} / ${progress.total.size} bytes`);
42
},
43
error: (error) => {
44
if (error instanceof QiniuRequestError) {
45
console.error(`Request failed with code ${error.code}:`, error.message);
46
} else if (error instanceof QiniuNetworkError) {
47
console.error('Network error:', error.message);
48
} else {
49
console.error('Upload error:', error.message);
50
}
51
},
52
complete: (response) => {
53
console.log('Upload completed successfully:', response);
54
// response contains server response data
55
}
56
});
57
58
// Upload with custom variables and metadata
59
const uploadWithMetadata = upload(file, 'user-photos/avatar.jpg', token, {
60
fname: file.name,
61
customVars: {
62
'x:userId': '12345',
63
'x:uploadSource': 'profile-page'
64
},
65
metadata: {
66
'x-qn-meta-author': 'John Doe',
67
'x-qn-meta-description': 'Profile avatar'
68
},
69
mimeType: 'image/jpeg'
70
}, {
71
region: region.z0,
72
useCdnDomain: true,
73
retryCount: 5,
74
chunkSize: 8, // 8MB chunks for large files
75
concurrentRequestLimit: 3
76
});
77
```
78
79
### Upload Configuration
80
81
Configuration options for controlling upload behavior and performance.
82
83
```typescript { .api }
84
interface Config {
85
/** Enable CDN domain for uploads (recommended) */
86
useCdnDomain?: boolean;
87
/** Upload region selection */
88
region?: typeof region[keyof typeof region];
89
/** Force direct upload even for large files */
90
forceDirect?: boolean;
91
/** Number of retry attempts on failure */
92
retryCount?: number;
93
/** Chunk size in MB for resumable uploads */
94
chunkSize?: number;
95
/** Maximum concurrent upload requests */
96
concurrentRequestLimit?: number;
97
/** Upload protocol */
98
upprotocol?: 'https' | 'http';
99
/** Disable statistics reporting */
100
disableStatisticsReport?: boolean;
101
}
102
```
103
104
### Upload Metadata
105
106
Additional information and custom data for uploads.
107
108
```typescript { .api }
109
interface Extra {
110
/** Original filename */
111
fname: string;
112
/** Custom variables (must start with 'x:') */
113
customVars?: { [key: string]: string };
114
/** Metadata (must start with 'x-qn-meta-') */
115
metadata?: { [key: string]: string };
116
/** MIME type override */
117
mimeType?: string;
118
}
119
```
120
121
**Custom Variables Example:**
122
123
```typescript
124
// Custom variables for application use
125
const putExtra = {
126
fname: 'document.pdf',
127
customVars: {
128
'x:userId': '12345',
129
'x:category': 'documents',
130
'x:public': 'false'
131
},
132
metadata: {
133
'x-qn-meta-title': 'Important Document',
134
'x-qn-meta-author': 'Jane Smith'
135
}
136
};
137
```
138
139
### Upload Progress Tracking
140
141
Detailed progress information during upload operations.
142
143
```typescript { .api }
144
interface UploadProgress {
145
/** Overall upload progress */
146
total: ProgressCompose;
147
/** Upload session information for resumable uploads */
148
uploadInfo?: UploadInfo;
149
/** Individual chunk progress for large files */
150
chunks?: ProgressCompose[];
151
}
152
153
interface ProgressCompose {
154
/** Total size in bytes */
155
size: number;
156
/** Bytes uploaded so far */
157
loaded: number;
158
/** Completion percentage (0-100) */
159
percent: number;
160
/** Whether data was loaded from cache (resume) */
161
fromCache?: boolean;
162
}
163
164
interface UploadInfo {
165
/** Upload session ID for resumable uploads */
166
id: string;
167
/** Upload endpoint URL */
168
url: string;
169
}
170
```
171
172
### Observable Interface
173
174
Upload function returns an Observable for reactive programming patterns.
175
176
```typescript { .api }
177
interface Observable<T, E, R> {
178
subscribe(observer: {
179
next?: (value: T) => void;
180
error?: (error: E) => void;
181
complete?: (result: R) => void;
182
}): Subscription;
183
}
184
185
interface Subscription {
186
/** Cancel the upload operation */
187
unsubscribe(): void;
188
}
189
```
190
191
**Advanced Usage Example:**
192
193
```typescript
194
import { upload, QiniuRequestError, QiniuNetworkError } from "qiniu-js";
195
196
let uploadSubscription;
197
198
function startUpload(file, token) {
199
uploadSubscription = upload(file, null, token, {
200
fname: file.name
201
}, {
202
region: region.z2,
203
retryCount: 3,
204
chunkSize: 4
205
}).subscribe({
206
next: (progress) => {
207
updateProgressBar(progress.total.percent);
208
209
// Show chunk details for large files
210
if (progress.chunks) {
211
progress.chunks.forEach((chunk, index) => {
212
console.log(`Chunk ${index}: ${chunk.percent}% ${chunk.fromCache ? '(cached)' : ''}`);
213
});
214
}
215
},
216
error: (error) => {
217
if (error instanceof QiniuRequestError) {
218
// Server returned an error
219
handleServerError(error.code, error.data);
220
} else if (error instanceof QiniuNetworkError) {
221
// Network connectivity issue
222
handleNetworkError();
223
} else {
224
// Other errors (validation, file issues, etc.)
225
handleGenericError(error.message);
226
}
227
},
228
complete: (response) => {
229
// Upload successful
230
console.log('File uploaded successfully:', response);
231
}
232
});
233
}
234
235
function cancelUpload() {
236
if (uploadSubscription) {
237
uploadSubscription.unsubscribe();
238
console.log('Upload cancelled');
239
}
240
}
241
```