mphttpx 2.3.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -994
- package/dist/mphttpx.cjs.js +24 -15
- package/dist/mphttpx.cjs.min.js +1 -1
- package/dist/mphttpx.esm.js +24 -15
- package/dist/mphttpx.esm.min.js +1 -1
- package/package.json +5 -5
- package/README.zh-CN.md +0 -983
package/README.md
CHANGED
|
@@ -1,994 +1,87 @@
|
|
|
1
|
-
# MPHTTPX
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
## Installation
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
npm install mphttpx
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Mini-Program Support
|
|
96
|
-
|
|
97
|
-
| WeChat | Alipay | Baidu | ByteDance | QQ | Kwai | JD | RedNote |
|
|
98
|
-
|:------:|:------:|:-----:|:---------:|:--:|:----:|:--:|:-------:|
|
|
99
|
-
| Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ |
|
|
100
|
-
|
|
101
|
-
Note: Modern browsers such as Chrome, Firefox, Edge, and Safari do not need these polyfills;
|
|
102
|
-
the relevant implementations imported from the mphttpx library will directly return the native functions of the browser.
|
|
103
|
-
|
|
104
|
-
## Usage
|
|
105
|
-
|
|
106
|
-
Note: Every module in mphttpx has a corresponding version with the same name ending in the letter P.
|
|
107
|
-
The difference between them is that the versions ending in P are polyfill implementations.
|
|
108
|
-
|
|
109
|
-
For example:
|
|
110
|
-
|
|
111
|
-
```javascript
|
|
112
|
-
// mphttpx does not modify globalThis in any way.
|
|
113
|
-
import { TextEncoder } from "mphttpx"; // returns the global object first; falls back to the polyfill if unavailable.
|
|
114
|
-
import { TextEncoderP } from "mphttpx"; // returns the polyfill directly.
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### TextEncoder
|
|
118
|
-
|
|
119
|
-
#### Example
|
|
120
|
-
|
|
121
|
-
```javascript
|
|
122
|
-
import { TextEncoder } from "mphttpx";
|
|
123
|
-
|
|
124
|
-
const encoder = new TextEncoder();
|
|
125
|
-
const encoded = encoder.encode("€");
|
|
126
|
-
|
|
127
|
-
console.log(encoded); // Uint8Array(3) [226, 130, 172]
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
#### Compatibility
|
|
131
|
-
|
|
132
|
-
Properties
|
|
133
|
-
|
|
134
|
-
| Property | Available | Description |
|
|
135
|
-
| --------- | --------- | -------------|
|
|
136
|
-
| encoding | ✔ | utf-8 |
|
|
137
|
-
|
|
138
|
-
Methods
|
|
139
|
-
|
|
140
|
-
| Method | Available | Description |
|
|
141
|
-
| ------- | --------- | -------------|
|
|
142
|
-
| encode(string) | ✔ |
|
|
143
|
-
| encodeInto(string, uint8Array) | ✔ |
|
|
144
|
-
|
|
145
|
-
### TextDecoder
|
|
146
|
-
|
|
147
|
-
#### Example
|
|
148
|
-
|
|
149
|
-
```javascript
|
|
150
|
-
import { TextDecoder } from "mphttpx";
|
|
151
|
-
|
|
152
|
-
const utf8decoder = new TextDecoder(); // default 'utf-8'
|
|
153
|
-
const encodedText = new Uint8Array([240, 160, 174, 183]);
|
|
154
|
-
|
|
155
|
-
console.log(utf8decoder.decode(encodedText)); // 𠮷
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
#### Compatibility
|
|
159
|
-
|
|
160
|
-
Properties
|
|
161
|
-
|
|
162
|
-
| Property | Available | Description |
|
|
163
|
-
| --------- | --------- | -------------|
|
|
164
|
-
| encoding | ✔ | only utf-8 |
|
|
165
|
-
| fatal | ✔ |
|
|
166
|
-
| ignoreBOM | ✔ |
|
|
167
|
-
|
|
168
|
-
Methods
|
|
169
|
-
|
|
170
|
-
| Method | Available | Description |
|
|
171
|
-
| ------- | --------- | -------------|
|
|
172
|
-
| decode() | ✔ |
|
|
173
|
-
| decode(buffer) | ✔ |
|
|
174
|
-
| decode(buffer, options) | ✔ |
|
|
175
|
-
|
|
176
|
-
### Blob
|
|
177
|
-
|
|
178
|
-
#### Example
|
|
179
|
-
|
|
180
|
-
Creating a blob
|
|
181
|
-
|
|
182
|
-
```javascript
|
|
183
|
-
import { Blob, fetch } from "mphttpx";
|
|
184
|
-
|
|
185
|
-
const obj = { hello: "world" };
|
|
186
|
-
const blob = new Blob([JSON.stringify(obj, null, 2)], {
|
|
187
|
-
type: "application/json",
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
const another_blob = new Blob(["Hello, World!"], {
|
|
191
|
-
type: "text/plain"
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
fetch("https://www.test.com/blob", {
|
|
195
|
-
method: "POST",
|
|
196
|
-
body: another_blob,
|
|
197
|
-
});
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
Extracting data from a blob
|
|
201
|
-
|
|
202
|
-
```javascript
|
|
203
|
-
import { Blob, FileReader, fetch } from "mphttpx";
|
|
204
|
-
|
|
205
|
-
const blob = new Blob([JSON.stringify({ foo: "bar" })], {
|
|
206
|
-
type: "application/json",
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
const reader = new FileReader();
|
|
210
|
-
reader.addEventListener("loadend", () => {
|
|
211
|
-
// reader.result contains the contents of blob as a typed array
|
|
212
|
-
});
|
|
213
|
-
reader.readAsArrayBuffer(blob);
|
|
214
|
-
|
|
215
|
-
fetch("https://www.test.com/blob", {
|
|
216
|
-
method: "POST",
|
|
217
|
-
body: blob,
|
|
218
|
-
})
|
|
219
|
-
.then(r => r.blob())
|
|
220
|
-
.then(r => {
|
|
221
|
-
const reader2 = new FileReader();
|
|
222
|
-
reader2.onload = () => {
|
|
223
|
-
// reader2.result
|
|
224
|
-
}
|
|
225
|
-
reader2.readAsDataURL(r); // base64
|
|
226
|
-
});
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
#### Compatibility
|
|
230
|
-
|
|
231
|
-
Properties
|
|
232
|
-
|
|
233
|
-
| Property | Available | Description |
|
|
234
|
-
| --------- | --------- | -------------|
|
|
235
|
-
| size | ✔ |
|
|
236
|
-
| type | ✔ |
|
|
237
|
-
|
|
238
|
-
Methods
|
|
239
|
-
|
|
240
|
-
| Method | Available | Description |
|
|
241
|
-
| ------- | --------- | -------------|
|
|
242
|
-
| arrayBuffer() | ✔ |
|
|
243
|
-
| bytes() | ✔ |
|
|
244
|
-
| slice() | ✔ |
|
|
245
|
-
| slice(start) | ✔ |
|
|
246
|
-
| slice(start, end) | ✔ |
|
|
247
|
-
| slice(start, end, contentType) | ✔ |
|
|
248
|
-
| stream() | ✖ |
|
|
249
|
-
| text() | ✔ |
|
|
250
|
-
|
|
251
|
-
### File
|
|
252
|
-
|
|
253
|
-
#### Example
|
|
254
|
-
|
|
255
|
-
```javascript
|
|
256
|
-
import { File } from "mphttpx";
|
|
257
|
-
|
|
258
|
-
const file = new File(["foo"], "foo.txt", {
|
|
259
|
-
type: "text/plain",
|
|
260
|
-
});
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
#### Compatibility
|
|
264
|
-
|
|
265
|
-
Properties
|
|
266
|
-
|
|
267
|
-
| Property | Available | Description |
|
|
268
|
-
| --------- | --------- | -------------|
|
|
269
|
-
| lastModified | ✔ |
|
|
270
|
-
| name | ✔ |
|
|
271
|
-
| webkitRelativePath | ✖ |
|
|
272
|
-
|
|
273
|
-
### FileReader
|
|
274
|
-
|
|
275
|
-
#### Example
|
|
276
|
-
|
|
277
|
-
```javascript
|
|
278
|
-
import { File, FileReader } from "mphttpx";
|
|
279
|
-
|
|
280
|
-
const file = new File([JSON.stringify({ foo: "bar" })], "test.json", {
|
|
281
|
-
type: "application/json",
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
// Read the file
|
|
285
|
-
const reader = new FileReader();
|
|
286
|
-
reader.onload = () => {
|
|
287
|
-
console.log(reader.result);
|
|
288
|
-
};
|
|
289
|
-
reader.readAsText(file);
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
#### Compatibility
|
|
293
|
-
|
|
294
|
-
Properties
|
|
295
|
-
|
|
296
|
-
| Property | Available | Description |
|
|
297
|
-
| --------- | --------- | -------------|
|
|
298
|
-
| error | ✔ |
|
|
299
|
-
| readyState | ✔ |
|
|
300
|
-
| result | ✔ |
|
|
301
|
-
|
|
302
|
-
Methods
|
|
303
|
-
|
|
304
|
-
| Method | Available | Description |
|
|
305
|
-
| ------- | --------- | -------------|
|
|
306
|
-
| abort() | ✔ | simulated |
|
|
307
|
-
| readAsArrayBuffer() | ✔ |
|
|
308
|
-
| readAsBinaryString() | ✔ |
|
|
309
|
-
| readAsDataURL() | ✔ |
|
|
310
|
-
| readAsText() | ✔ | only utf-8 |
|
|
311
|
-
|
|
312
|
-
### URLSearchParams
|
|
313
|
-
|
|
314
|
-
#### Example
|
|
315
|
-
|
|
316
|
-
```javascript
|
|
317
|
-
import { URLSearchParams, fetch } from "mphttpx";
|
|
318
|
-
|
|
319
|
-
const paramsString = "q=URLUtils.searchParams&topic=api";
|
|
320
|
-
const searchParams = new URLSearchParams(paramsString);
|
|
321
|
-
|
|
322
|
-
// Iterating the search parameters
|
|
323
|
-
for (const p of searchParams) {
|
|
324
|
-
console.log(p);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
console.log(searchParams.has("topic")); // true
|
|
328
|
-
console.log(searchParams.has("topic", "fish")); // false
|
|
329
|
-
console.log(searchParams.get("topic") === "api"); // true
|
|
330
|
-
console.log(searchParams.getAll("topic")); // ["api"]
|
|
331
|
-
console.log(searchParams.get("foo") === null); // true
|
|
332
|
-
console.log(searchParams.append("topic", "webdev"));
|
|
333
|
-
console.log(searchParams.toString()); // "q=URLUtils.searchParams&topic=api&topic=webdev"
|
|
334
|
-
console.log(searchParams.set("topic", "More webdev"));
|
|
335
|
-
console.log(searchParams.toString()); // "q=URLUtils.searchParams&topic=More+webdev"
|
|
336
|
-
console.log(searchParams.delete("topic"));
|
|
337
|
-
console.log(searchParams.toString()); // "q=URLUtils.searchParams"
|
|
338
|
-
|
|
339
|
-
// GET
|
|
340
|
-
fetch("https://www.test.com/get" + `?${searchParams.toString()}`);
|
|
341
|
-
|
|
342
|
-
// POST
|
|
343
|
-
fetch("https://www.test.com/post", {
|
|
344
|
-
method: "POST",
|
|
345
|
-
body: searchParams,
|
|
346
|
-
});
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
Search parameters can also be an object.
|
|
350
|
-
|
|
351
|
-
```javascript
|
|
352
|
-
import { URLSearchParams } from "mphttpx";
|
|
353
|
-
|
|
354
|
-
const paramsObj = { foo: "bar", baz: "bar" };
|
|
355
|
-
const searchParams = new URLSearchParams(paramsObj);
|
|
356
|
-
|
|
357
|
-
console.log(searchParams.toString()); // "foo=bar&baz=bar"
|
|
358
|
-
console.log(searchParams.has("foo")); // true
|
|
359
|
-
console.log(searchParams.get("foo")); // "bar"
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
#### Compatibility
|
|
363
|
-
|
|
364
|
-
Properties
|
|
365
|
-
|
|
366
|
-
| Property | Available | Description |
|
|
367
|
-
| --------- | --------- | -------------|
|
|
368
|
-
| size | ✔ |
|
|
369
|
-
|
|
370
|
-
Methods
|
|
371
|
-
|
|
372
|
-
| Method | Available | Description |
|
|
373
|
-
| ------- | --------- | -------------|
|
|
374
|
-
| append(name, value) | ✔ |
|
|
375
|
-
| delete(name) | ✔ |
|
|
376
|
-
| delete(name, value) | ✔ |
|
|
377
|
-
| entries() | ✔ |
|
|
378
|
-
| forEach(callback) | ✔ |
|
|
379
|
-
| forEach(callback, thisArg) | ✔ |
|
|
380
|
-
| get(name) | ✔ |
|
|
381
|
-
| getAll(name) | ✔ |
|
|
382
|
-
| has(name) | ✔ |
|
|
383
|
-
| has(name, value) | ✔ |
|
|
384
|
-
| keys() | ✔ |
|
|
385
|
-
| set(name, value) | ✔ |
|
|
386
|
-
| sort() | ✔ |
|
|
387
|
-
| toString() | ✔ |
|
|
388
|
-
| values() | ✔ |
|
|
389
|
-
|
|
390
|
-
### FormData
|
|
391
|
-
|
|
392
|
-
#### Example
|
|
393
|
-
|
|
394
|
-
```javascript
|
|
395
|
-
import { FormData, fetch } from "mphttpx";
|
|
396
|
-
|
|
397
|
-
const formData = new FormData();
|
|
398
|
-
formData.append("username", "Chris");
|
|
399
|
-
|
|
400
|
-
const file = new File(["Hello, World!"], "file.txt", {
|
|
401
|
-
type: "text/plain",
|
|
402
|
-
});
|
|
403
|
-
formData.append("file", file);
|
|
404
|
-
|
|
405
|
-
fetch("https://www.test.com/formdata", {
|
|
406
|
-
method: "POST",
|
|
407
|
-
body: formData,
|
|
408
|
-
});
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
#### Compatibility
|
|
412
|
-
|
|
413
|
-
Constructors
|
|
414
|
-
|
|
415
|
-
| Constructor | Available | Description |
|
|
416
|
-
| ----------- | --------- | -------------|
|
|
417
|
-
| new FormData() | ✔ |
|
|
418
|
-
| new FormData(form) | ✖ |
|
|
419
|
-
| new FormData(form, submitter) | ✖ |
|
|
420
|
-
|
|
421
|
-
Methods
|
|
422
|
-
|
|
423
|
-
| Method | Available | Description |
|
|
424
|
-
| ------- | --------- | -------------|
|
|
425
|
-
| append(name, value) | ✔ |
|
|
426
|
-
| append(name, value, filename) | ✔ |
|
|
427
|
-
| delete(name) | ✔ |
|
|
428
|
-
| entries() | ✔ |
|
|
429
|
-
| get(name) | ✔ |
|
|
430
|
-
| getAll(name) | ✔ |
|
|
431
|
-
| has(name) | ✔ |
|
|
432
|
-
| keys() | ✔ |
|
|
433
|
-
| set(name, value) | ✔ |
|
|
434
|
-
| set(name, value, filename) | ✔ |
|
|
435
|
-
| values() | ✔ |
|
|
436
|
-
|
|
437
|
-
### fetch
|
|
438
|
-
|
|
439
|
-
#### Example
|
|
440
|
-
|
|
441
|
-
```javascript
|
|
442
|
-
import { fetch } from "mphttpx";
|
|
443
|
-
|
|
444
|
-
fetch("http://example.com/movies.json")
|
|
445
|
-
.then((response) => response.json())
|
|
446
|
-
.then((data) => console.log(data));
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
Using fetch() to POST JSON data
|
|
450
|
-
|
|
451
|
-
```javascript
|
|
452
|
-
import { fetch } from "mphttpx";
|
|
453
|
-
|
|
454
|
-
const data = { username: "example" };
|
|
455
|
-
|
|
456
|
-
fetch("https://example.com/profile", {
|
|
457
|
-
method: "POST", // or 'PUT'
|
|
458
|
-
headers: {
|
|
459
|
-
"Content-Type": "application/json",
|
|
460
|
-
},
|
|
461
|
-
body: JSON.stringify(data),
|
|
462
|
-
})
|
|
463
|
-
.then((response) => response.json())
|
|
464
|
-
.then((data) => {
|
|
465
|
-
console.log("Success:", data);
|
|
466
|
-
})
|
|
467
|
-
.catch((error) => {
|
|
468
|
-
console.error("Error:", error);
|
|
469
|
-
});
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
Uploading files
|
|
473
|
-
|
|
474
|
-
```javascript
|
|
475
|
-
import { fetch, File, FormData } from "mphttpx";
|
|
476
|
-
|
|
477
|
-
const formData = new FormData();
|
|
478
|
-
|
|
479
|
-
formData.append("username", "abc123");
|
|
480
|
-
formData.append("file", new File(["foo"], "foo.txt", { type: "text/plain" }));
|
|
481
|
-
|
|
482
|
-
fetch("https://example.com/profile/avatar", {
|
|
483
|
-
method: "PUT",
|
|
484
|
-
body: formData,
|
|
485
|
-
})
|
|
486
|
-
.then((response) => response.json())
|
|
487
|
-
.then((result) => {
|
|
488
|
-
console.log("Success:", result);
|
|
489
|
-
})
|
|
490
|
-
.catch((error) => {
|
|
491
|
-
console.error("Error:", error);
|
|
492
|
-
});
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
Note: The fetch method of mphttpx is implemented based on XMLHttpRequest, and this underlying implementation is replaceable.
|
|
496
|
-
|
|
497
|
-
```javascript
|
|
498
|
-
import { setXMLHttpRequest } from "mphttpx";
|
|
499
|
-
setXMLHttpRequest(another_XMLHttpRequest); // custom XMLHttpRequest implementation
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
| Syntax | Available | Description |
|
|
503
|
-
| ------- | --------- | -------------|
|
|
504
|
-
| fetch(resource) | ✔ |
|
|
505
|
-
| fetch(resource, options) | ✔ |
|
|
506
|
-
|
|
507
|
-
#### Compatibility
|
|
508
|
-
|
|
509
|
-
Refer to Request below.
|
|
510
|
-
|
|
511
|
-
### Request
|
|
512
|
-
|
|
513
|
-
#### Example
|
|
514
|
-
|
|
515
|
-
```javascript
|
|
516
|
-
import { fetch, Request } from "mphttpx";
|
|
517
|
-
|
|
518
|
-
const request = new Request("https://www.mozilla.org/favicon.ico");
|
|
519
|
-
|
|
520
|
-
const url = request.url;
|
|
521
|
-
const method = request.method;
|
|
522
|
-
const credentials = request.credentials;
|
|
523
|
-
|
|
524
|
-
fetch(request)
|
|
525
|
-
.then((response) => response.blob())
|
|
526
|
-
.then((blob) => {
|
|
527
|
-
console.log(blob);
|
|
528
|
-
});
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
```javascript
|
|
532
|
-
import { fetch, Request } from "mphttpx";
|
|
533
|
-
|
|
534
|
-
const request = new Request("https://example.com", {
|
|
535
|
-
method: "POST",
|
|
536
|
-
body: '{"foo": "bar"}',
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
const url = request.url;
|
|
540
|
-
const method = request.method;
|
|
541
|
-
const credentials = request.credentials;
|
|
542
|
-
const bodyUsed = request.bodyUsed;
|
|
543
|
-
|
|
544
|
-
fetch(request)
|
|
545
|
-
.then((response) => {
|
|
546
|
-
if (response.status === 200) {
|
|
547
|
-
return response.json();
|
|
548
|
-
} else {
|
|
549
|
-
throw new Error("Something went wrong on API server!");
|
|
550
|
-
}
|
|
551
|
-
})
|
|
552
|
-
.then((response) => {
|
|
553
|
-
console.debug(response);
|
|
554
|
-
// …
|
|
555
|
-
})
|
|
556
|
-
.catch((error) => {
|
|
557
|
-
console.error(error);
|
|
558
|
-
});
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
#### Compatibility
|
|
562
|
-
|
|
563
|
-
Properties
|
|
564
|
-
|
|
565
|
-
| Property | Available | Description |
|
|
566
|
-
| --------- | --------- | -------------|
|
|
567
|
-
| body | ✖ |
|
|
568
|
-
| bodyUsed | ✔ |
|
|
569
|
-
| cache | ✔ |
|
|
570
|
-
| credentials | ✔ |
|
|
571
|
-
| destination | ✖ |
|
|
572
|
-
| headers | ✔ |
|
|
573
|
-
| integrity | ✖ |
|
|
574
|
-
| keepalive | ✖ |
|
|
575
|
-
| method | ✔ |
|
|
576
|
-
| mode | ✖ |
|
|
577
|
-
| redirect | ✖ |
|
|
578
|
-
| referrer | ✖ |
|
|
579
|
-
| referrerPolicy | ✖ |
|
|
580
|
-
| signal | ✔ |
|
|
581
|
-
| url | ✔ |
|
|
582
|
-
|
|
583
|
-
Methods
|
|
584
|
-
|
|
585
|
-
| Method | Available | Description |
|
|
586
|
-
| ------- | --------- | -------------|
|
|
587
|
-
| arrayBuffer() | ✔ |
|
|
588
|
-
| blob() | ✔ |
|
|
589
|
-
| bytes() | ✔ |
|
|
590
|
-
| clone() | ✔ |
|
|
591
|
-
| formData() | ✔ |
|
|
592
|
-
| json() | ✔ |
|
|
593
|
-
| text() | ✔ |
|
|
594
|
-
|
|
595
|
-
### Response
|
|
596
|
-
|
|
597
|
-
#### Example
|
|
598
|
-
|
|
599
|
-
```javascript
|
|
600
|
-
import { Response, Blob, fetch } from "mphttpx";
|
|
601
|
-
|
|
602
|
-
const myBlob = new Blob();
|
|
603
|
-
const myOptions = { status: 200, statusText: "SuperSmashingGreat!" };
|
|
604
|
-
const myResponse = new Response(myBlob, myOptions);
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
#### Compatibility
|
|
608
|
-
|
|
609
|
-
Properties
|
|
610
|
-
|
|
611
|
-
| Property | Available | Description |
|
|
612
|
-
| --------- | --------- | -------------|
|
|
613
|
-
| body | ✖ |
|
|
614
|
-
| bodyUsed | ✔ |
|
|
615
|
-
| headers | ✔ |
|
|
616
|
-
| ok | ✔ |
|
|
617
|
-
| redirected | ✖ |
|
|
618
|
-
| status | ✔ |
|
|
619
|
-
| statusText | ✔ |
|
|
620
|
-
| type | ✖ |
|
|
621
|
-
| url | ✔ |
|
|
622
|
-
|
|
623
|
-
Methods
|
|
624
|
-
|
|
625
|
-
| Method | Available | Description |
|
|
626
|
-
| ------- | --------- | -------------|
|
|
627
|
-
| arrayBuffer() | ✔ |
|
|
628
|
-
| blob() | ✔ |
|
|
629
|
-
| bytes() | ✔ |
|
|
630
|
-
| clone() | ✔ |
|
|
631
|
-
| formData() | ✔ |
|
|
632
|
-
| json() | ✔ |
|
|
633
|
-
| text() | ✔ |
|
|
634
|
-
|
|
635
|
-
### Headers
|
|
636
|
-
|
|
637
|
-
#### Example
|
|
638
|
-
|
|
639
|
-
```javascript
|
|
640
|
-
import { Headers, fetch } from "mphttpx";
|
|
641
|
-
|
|
642
|
-
const myHeaders = new Headers();
|
|
643
|
-
|
|
644
|
-
myHeaders.append("Content-Type", "text/plain");
|
|
645
|
-
myHeaders.get("Content-Type"); // should return 'text/plain'
|
|
646
|
-
|
|
647
|
-
fetch("https://www.test.com/headers", {
|
|
648
|
-
headers: myHeaders,
|
|
649
|
-
});
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
The same can be achieved by passing an array of arrays or an object literal to the constructor:
|
|
653
|
-
|
|
654
|
-
```javascript
|
|
655
|
-
import { Headers } from "mphttpx";
|
|
656
|
-
|
|
657
|
-
let myHeaders = new Headers({
|
|
658
|
-
"Content-Type": "text/plain",
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
// or, using an array of arrays:
|
|
662
|
-
myHeaders = new Headers([["Content-Type", "text/plain"]]);
|
|
663
|
-
|
|
664
|
-
myHeaders.get("Content-Type"); // should return 'text/plain'
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
#### Compatibility
|
|
668
|
-
|
|
669
|
-
Methods
|
|
670
|
-
|
|
671
|
-
| Method | Available | Description |
|
|
672
|
-
| ------- | --------- | -------------|
|
|
673
|
-
| append(name, value) | ✔ |
|
|
674
|
-
| delete(name) | ✔ |
|
|
675
|
-
| entries() | ✔ |
|
|
676
|
-
| forEach(callbackFn) | ✔ |
|
|
677
|
-
| forEach(callbackFn, thisArg) | ✔ |
|
|
678
|
-
| get(name) | ✔ |
|
|
679
|
-
| getSetCookie() | ✔ |
|
|
680
|
-
| has(name) | ✔ |
|
|
681
|
-
| keys() | ✔ |
|
|
682
|
-
| set(name, value) | ✔ |
|
|
683
|
-
| values() | ✔ |
|
|
684
|
-
|
|
685
|
-
### AbortController
|
|
686
|
-
|
|
687
|
-
#### Example
|
|
688
|
-
|
|
689
|
-
```javascript
|
|
690
|
-
import { AbortController, fetch } from "mphttpx";
|
|
691
|
-
|
|
692
|
-
const controller = new AbortController();
|
|
693
|
-
|
|
694
|
-
fetch("https://www.test.com/abort", {
|
|
695
|
-
signal: controller.signal,
|
|
696
|
-
});
|
|
697
|
-
```
|
|
698
|
-
|
|
699
|
-
```javascript
|
|
700
|
-
import { AbortController, AbortSignal, Request, fetch } from "mphttpx";
|
|
701
|
-
|
|
702
|
-
async function get() {
|
|
703
|
-
const controller = new AbortController();
|
|
704
|
-
const request = new Request("https://example.org/get", {
|
|
705
|
-
signal: controller.signal,
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
const response = await fetch(request);
|
|
709
|
-
controller.abort();
|
|
710
|
-
// The next line will throw `AbortError`
|
|
711
|
-
const text = await response.text();
|
|
712
|
-
console.log(text);
|
|
713
|
-
}
|
|
714
|
-
```
|
|
715
|
-
|
|
716
|
-
#### Compatibility
|
|
717
|
-
|
|
718
|
-
AbortController Properties
|
|
719
|
-
|
|
720
|
-
| Property | Available | Description |
|
|
721
|
-
| --------- | --------- | -------------|
|
|
722
|
-
| signal | ✔ |
|
|
723
|
-
|
|
724
|
-
AbortController Methods
|
|
725
|
-
|
|
726
|
-
| Method | Available | Description |
|
|
727
|
-
| ------- | --------- | -------------|
|
|
728
|
-
| abort() | ✔ |
|
|
729
|
-
| abort(reason) | ✔ |
|
|
730
|
-
|
|
731
|
-
AbortSignal Properties
|
|
732
|
-
|
|
733
|
-
| Property | Available | Description |
|
|
734
|
-
| --------- | --------- | -------------|
|
|
735
|
-
| aborted | ✔ |
|
|
736
|
-
| reason | ✔ |
|
|
737
|
-
|
|
738
|
-
AbortSignal Methods
|
|
739
|
-
|
|
740
|
-
| Method | Available | Description |
|
|
741
|
-
| ------- | --------- | -------------|
|
|
742
|
-
| throwIfAborted() | ✔ |
|
|
743
|
-
|
|
744
|
-
### EventTarget
|
|
745
|
-
|
|
746
|
-
#### Example
|
|
747
|
-
|
|
748
|
-
```javascript
|
|
749
|
-
import { EventTarget, Event, CustomEvent } from "mphttpx";
|
|
750
|
-
|
|
751
|
-
const target = new EventTarget();
|
|
752
|
-
|
|
753
|
-
target.addEventListener("foo", function (evt) {
|
|
754
|
-
console.log(evt);
|
|
755
|
-
});
|
|
756
|
-
|
|
757
|
-
const evt = new Event("foo");
|
|
758
|
-
target.dispatchEvent(evt);
|
|
759
|
-
|
|
760
|
-
target.addEventListener("animalfound", function (evt) {
|
|
761
|
-
console.log(evt.detail.name);
|
|
762
|
-
});
|
|
763
|
-
|
|
764
|
-
const catFound = new CustomEvent("animalfound", {
|
|
765
|
-
detail: {
|
|
766
|
-
name: "cat",
|
|
767
|
-
},
|
|
768
|
-
});
|
|
769
|
-
target.dispatchEvent(catFound);
|
|
770
|
-
```
|
|
771
|
-
|
|
772
|
-
#### Compatibility
|
|
773
|
-
|
|
774
|
-
Methods
|
|
775
|
-
|
|
776
|
-
| Method | Available | Description |
|
|
777
|
-
| ------- | --------- | -------------|
|
|
778
|
-
| addEventListener(type, listener) | ✔ |
|
|
779
|
-
| addEventListener(type, listener, options) | ✔ |
|
|
780
|
-
| addEventListener(type, listener, useCapture) | ✔ |
|
|
781
|
-
| dispatchEvent(event) | ✔ |
|
|
782
|
-
| removeEventListener(type, listener) | ✔ |
|
|
783
|
-
| removeEventListener(type, listener, options) | ✔ |
|
|
784
|
-
| removeEventListener(type, listener, useCapture) | ✔ |
|
|
785
|
-
|
|
786
|
-
### XMLHttpRequest (mini-programs)
|
|
787
|
-
|
|
788
|
-
#### Example
|
|
789
|
-
|
|
790
|
-
GET
|
|
791
|
-
|
|
792
|
-
```javascript
|
|
793
|
-
import { XMLHttpRequest } from "mphttpx";
|
|
794
|
-
|
|
795
|
-
const xhr = new XMLHttpRequest();
|
|
796
|
-
xhr.open("GET", "https://example.com/server?foo=bar&lorem=ipsum");
|
|
797
|
-
|
|
798
|
-
xhr.onload = () => {
|
|
799
|
-
// Request finished. Do processing here.
|
|
800
|
-
};
|
|
801
|
-
|
|
802
|
-
xhr.send();
|
|
803
|
-
```
|
|
804
|
-
|
|
805
|
-
POST
|
|
806
|
-
|
|
807
|
-
```javascript
|
|
808
|
-
import { XMLHttpRequest } from "mphttpx";
|
|
809
|
-
|
|
810
|
-
const xhr = new XMLHttpRequest();
|
|
811
|
-
xhr.open("POST", "https://example.com/server");
|
|
812
|
-
|
|
813
|
-
// Send the proper header information along with the request
|
|
814
|
-
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
815
|
-
|
|
816
|
-
xhr.onreadystatechange = () => {
|
|
817
|
-
// Call a function when the state changes.
|
|
818
|
-
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
|
819
|
-
// Request finished. Do processing here.
|
|
820
|
-
}
|
|
821
|
-
};
|
|
822
|
-
|
|
823
|
-
xhr.send(JSON.stringify({ foo: "bar", lorem: "ipsum" }));
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
#### Compatibility
|
|
827
|
-
|
|
828
|
-
Properties
|
|
829
|
-
|
|
830
|
-
| Property | Available | Description |
|
|
831
|
-
| --------- | --------- | -------------|
|
|
832
|
-
| readyState | ✔ | 2, 3: simulated |
|
|
833
|
-
| response | ✔ |
|
|
834
|
-
| responseText | ✔ |
|
|
835
|
-
| responseType | ✔ | The `"document"` is not supported |
|
|
836
|
-
| responseURL | ✔ | The `responseURL` returns the URL used in the original request. |
|
|
837
|
-
| responseXML | ✖ |
|
|
838
|
-
| status | ✔ |
|
|
839
|
-
| statusText | ✔ |
|
|
840
|
-
| timeout | ✔ | This value must be less than the default timeout of mini-programs. |
|
|
841
|
-
| upload | ✔ | simulated |
|
|
842
|
-
| withCredentials | ✖ |
|
|
843
|
-
|
|
844
|
-
Methods
|
|
845
|
-
|
|
846
|
-
| Method | Available | Description |
|
|
847
|
-
| ------- | --------- | -------------|
|
|
848
|
-
| abort() | ✔ |
|
|
849
|
-
| getAllResponseHeaders() | ✔ |
|
|
850
|
-
| getResponseHeader(headerName) | ✔ |
|
|
851
|
-
| open(method, url) | ✔ |
|
|
852
|
-
| open(method, url, async) | ✔ |
|
|
853
|
-
| open(method, url, async, user) | ✔ |
|
|
854
|
-
| open(method, url, async, user, password) | ✔ |
|
|
855
|
-
| overrideMimeType(mimeType) | ✖ |
|
|
856
|
-
| send() | ✔ |
|
|
857
|
-
| send(body) | ✔ |
|
|
858
|
-
| setRequestHeader(header, value) | ✔ |
|
|
859
|
-
|
|
860
|
-
### WebSocket (mini-programs, since 1.1.0)
|
|
861
|
-
|
|
862
|
-
#### Example
|
|
863
|
-
|
|
864
|
-
```javascript
|
|
865
|
-
import { WebSocket } from "mphttpx";
|
|
866
|
-
|
|
867
|
-
// Create WebSocket connection.
|
|
868
|
-
const socket = new WebSocket("wss://example.com:8080");
|
|
869
|
-
|
|
870
|
-
// Change binary type from "blob" to "arraybuffer"
|
|
871
|
-
socket.binaryType = "arraybuffer";
|
|
872
|
-
|
|
873
|
-
// Listen for messages
|
|
874
|
-
socket.addEventListener("message", (event) => {
|
|
875
|
-
if (event.data instanceof ArrayBuffer) {
|
|
876
|
-
// binary frame
|
|
877
|
-
const view = new DataView(event.data);
|
|
878
|
-
console.log(view.getInt32(0));
|
|
879
|
-
} else {
|
|
880
|
-
// text frame
|
|
881
|
-
console.log(event.data);
|
|
882
|
-
}
|
|
883
|
-
});
|
|
884
|
-
```
|
|
885
|
-
|
|
886
|
-
#### Compatibility
|
|
887
|
-
|
|
888
|
-
Properties
|
|
889
|
-
|
|
890
|
-
| Property | Available | Description |
|
|
891
|
-
| --------- | --------- | -------------|
|
|
892
|
-
| binaryType | ✔ |
|
|
893
|
-
| bufferedAmount | ✖ |
|
|
894
|
-
| extensions | ✖ |
|
|
895
|
-
| protocol | ✔ |
|
|
896
|
-
| readyState | ✔ |
|
|
897
|
-
| url | ✔ |
|
|
898
|
-
|
|
899
|
-
Methods
|
|
900
|
-
|
|
901
|
-
| Method | Available | Description |
|
|
902
|
-
| ------- | --------- | -------------|
|
|
903
|
-
| close() | ✔ |
|
|
904
|
-
| close(code) | ✔ |
|
|
905
|
-
| close(code, reason) | ✔ |
|
|
906
|
-
| send(data) | ✔ |
|
|
907
|
-
|
|
908
|
-
## Auto Import
|
|
909
|
-
|
|
910
|
-
See [unplugin-auto-import][2] for more details.
|
|
911
|
-
|
|
912
|
-
```javascript
|
|
913
|
-
// for reference only
|
|
914
|
-
AutoImport({
|
|
915
|
-
// other configs
|
|
916
|
-
|
|
917
|
-
imports: [
|
|
918
|
-
// other imports
|
|
919
|
-
|
|
920
|
-
{
|
|
921
|
-
"mphttpx": [
|
|
922
|
-
"TextEncoder",
|
|
923
|
-
"TextDecoder",
|
|
924
|
-
|
|
925
|
-
"Blob",
|
|
926
|
-
"File",
|
|
927
|
-
"FileReader",
|
|
928
|
-
|
|
929
|
-
"URLSearchParams",
|
|
930
|
-
"FormData",
|
|
931
|
-
|
|
932
|
-
"fetch",
|
|
933
|
-
"Headers",
|
|
934
|
-
"Request",
|
|
935
|
-
"Response",
|
|
936
|
-
|
|
937
|
-
"AbortController",
|
|
938
|
-
"AbortSignal",
|
|
939
|
-
|
|
940
|
-
"EventTarget",
|
|
941
|
-
"Event",
|
|
942
|
-
"CustomEvent",
|
|
943
|
-
|
|
944
|
-
"XMLHttpRequest", // mini-programs
|
|
945
|
-
"WebSocket", // mini-programs
|
|
946
|
-
],
|
|
947
|
-
},
|
|
948
|
-
|
|
949
|
-
// other imports
|
|
950
|
-
],
|
|
951
|
-
|
|
952
|
-
// other configs
|
|
953
|
-
});
|
|
954
|
-
```
|
|
955
|
-
|
|
956
|
-
Note for `UniApp` developers: If your project is a UniApp mini-program created via HBuilderX using the legacy Vue2 template,
|
|
957
|
-
try installing an older version of the unplugin-auto-import plugin that supports CMD, such as version 0.16.7.
|
|
958
|
-
|
|
959
|
-
## UniApp & Taro
|
|
960
|
-
|
|
961
|
-
```javascript
|
|
962
|
-
import { setRequest } from "mphttpx";
|
|
963
|
-
import { setConnectSocket } from "mphttpx";
|
|
964
|
-
|
|
965
|
-
setRequest(uni.request);
|
|
966
|
-
// setRequest(Taro.request);
|
|
967
|
-
|
|
968
|
-
setConnectSocket(uni.connectSocket);
|
|
969
|
-
// setConnectSocket(Taro.connectSocket);
|
|
970
|
-
```
|
|
971
|
-
|
|
972
|
-
Note: When using in UniApp or Taro, if `fetch`, `XMLHttpRequest` or `WebSocket` fails to work, try explicitly setting the request/connectSocket function.
|
|
973
|
-
|
|
974
|
-
## Node.js
|
|
975
|
-
|
|
976
|
-
```bash
|
|
977
|
-
npm install xhr2
|
|
978
|
-
```
|
|
979
|
-
|
|
980
|
-
```javascript
|
|
981
|
-
import XMLHttpRequest from "xhr2";
|
|
982
|
-
import { setXMLHttpRequest } from "mphttpx";
|
|
983
|
-
|
|
984
|
-
setXMLHttpRequest(XMLHttpRequest);
|
|
985
|
-
```
|
|
986
|
-
|
|
987
|
-
## License
|
|
988
|
-
|
|
989
|
-
MIT
|
|
990
|
-
|
|
991
|
-
[0]: https://github.com/eligrey/Blob.js
|
|
992
|
-
[1]: https://github.com/github/fetch
|
|
993
|
-
[2]: https://www.npmjs.com/package/unplugin-auto-import
|
|
994
|
-
[3]: https://github.com/baoxingzeng/mphttpx/blob/main/README.zh-CN.md
|
|
1
|
+
# MPHTTPX
|
|
2
|
+
|
|
3
|
+
小程序中浏览器网络 API 的完整 polyfill 实现,一次安装即可使用 `fetch`、`XMLHttpRequest`、`WebSocket` 等符合 W3C 标准的应用程序编程接口。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install mphttpx
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 快速开始
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { fetch } from "mphttpx";
|
|
17
|
+
|
|
18
|
+
fetch("https://api.example.com/data")
|
|
19
|
+
.then(r => r.json())
|
|
20
|
+
.then(r => console.log(r));
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 功能模块
|
|
24
|
+
|
|
25
|
+
| API | 来源 |
|
|
26
|
+
| -------------------------------------------- | ------------------------------- |
|
|
27
|
+
| `fetch` / `Headers` / `Request` / `Response` | fetch-xhr-shim |
|
|
28
|
+
| `Blob` / `File` / `FileReader` | fetch-xhr-shim |
|
|
29
|
+
| `URLSearchParams` / `FormData` | fetch-xhr-shim |
|
|
30
|
+
| `AbortController` / `AbortSignal` | fetch-xhr-shim |
|
|
31
|
+
| `EventTarget` / `Event` / `CustomEvent` | fetch-xhr-shim |
|
|
32
|
+
| `TextEncoder` / `TextDecoder` | fetch-xhr-shim |
|
|
33
|
+
| `XMLHttpRequest` | miniprogram-xmlhttprequest-shim |
|
|
34
|
+
| `WebSocket` | miniprogram-websocket |
|
|
35
|
+
|
|
36
|
+
每个 API 都有对应的 `P` 后缀版本(如 `fetchP`、`BlobP`、`TextEncoderP`),始终返回 polyfill 实现,请按需使用。
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
import { fetch, Blob } from "mphttpx"; // 优先返回全局对象,不存在时返回 polyfill
|
|
40
|
+
import { fetchP, BlobP } from "mphttpx"; // 始终返回 polyfill 实现
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 依赖库
|
|
44
|
+
|
|
45
|
+
| 库 | 提供的 API |
|
|
46
|
+
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| [fetch-xhr-shim](https://www.npmjs.com/package/fetch-xhr-shim) | fetch、Headers、Request、Response、<br>Blob、File、FileReader、<br>URLSearchParams、FormData、<br>AbortController、AbortSignal、<br>EventTarget、Event、CustomEvent、<br>TextEncoder、TextDecoder |
|
|
48
|
+
| [miniprogram-xmlhttprequest-shim](https://www.npmjs.com/package/miniprogram-xmlhttprequest-shim) | XMLHttpRequest、<br>Cookie、enableCookie |
|
|
49
|
+
| [miniprogram-websocket](https://www.npmjs.com/package/miniprogram-websocket) | WebSocket |
|
|
50
|
+
|
|
51
|
+
各 API 的详细文档及兼容性说明请参阅对应库的自述文档。
|
|
52
|
+
|
|
53
|
+
## 兼容性
|
|
54
|
+
|
|
55
|
+
| 微信 | 支付宝 | 百度 | 抖音 | QQ | 快手 | 京东 | 小红书 |
|
|
56
|
+
| :---: | :----: | :---: | :---: | :---: | :---: | :---: | :----: |
|
|
57
|
+
| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
58
|
+
|
|
59
|
+
在 Chrome、Firefox、Edge、Safari 等浏览器中,所有导出均直接使用浏览器原生实现,无性能损耗。
|
|
60
|
+
|
|
61
|
+
## 注意事项
|
|
62
|
+
|
|
63
|
+
- **支付宝小程序**:`fetch`、`XMLHttpRequest`、`WebSocket` 等为保留字,导入时建议重命名:`import { fetch as fetchPolyfill } from "mphttpx";`。
|
|
64
|
+
|
|
65
|
+
## 开源协议
|
|
66
|
+
|
|
67
|
+
MIT License
|
|
68
|
+
|
|
69
|
+
Copyright (c) 2026
|
|
70
|
+
|
|
71
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
72
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
73
|
+
in the Software without restriction, including without limitation the rights
|
|
74
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
75
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
76
|
+
furnished to do so, subject to the following conditions:
|
|
77
|
+
|
|
78
|
+
The above copyright notice and this permission notice shall be included in all
|
|
79
|
+
copies or substantial portions of the Software.
|
|
80
|
+
|
|
81
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
82
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
83
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
84
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
85
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
86
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
87
|
+
SOFTWARE.
|