mphttpx 1.0.12 → 1.2.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.
@@ -0,0 +1,982 @@
1
+ # MPHTTPX 中文文档
2
+
3
+ `mphttpx`旨在为小程序提供与浏览器一致的请求开发体验,通过引入此库即可在小程序中使用XMLHttpRequest、fetch和FormData等浏览器请求相关功能。
4
+
5
+ ## 目录
6
+
7
+ - [MPHTTPX 中文文档](#mphttpx-中文文档)
8
+ - [目录](#目录)
9
+ - [功能](#功能)
10
+ - [安装](#安装)
11
+ - [小程序支持情况](#小程序支持情况)
12
+ - [使用](#使用)
13
+ - [TextEncoder](#textencoder)
14
+ - [示例](#示例)
15
+ - [兼容性](#兼容性)
16
+ - [TextDecoder](#textdecoder)
17
+ - [示例](#示例-1)
18
+ - [兼容性](#兼容性-1)
19
+ - [Blob](#blob)
20
+ - [示例](#示例-2)
21
+ - [兼容性](#兼容性-2)
22
+ - [File](#file)
23
+ - [示例](#示例-3)
24
+ - [兼容性](#兼容性-3)
25
+ - [FileReader](#filereader)
26
+ - [示例](#示例-4)
27
+ - [兼容性](#兼容性-4)
28
+ - [URLSearchParams](#urlsearchparams)
29
+ - [示例](#示例-5)
30
+ - [兼容性](#兼容性-5)
31
+ - [FormData](#formdata)
32
+ - [示例](#示例-6)
33
+ - [兼容性](#兼容性-6)
34
+ - [fetch](#fetch)
35
+ - [示例](#示例-7)
36
+ - [兼容性](#兼容性-7)
37
+ - [Request](#request)
38
+ - [示例](#示例-8)
39
+ - [兼容性](#兼容性-8)
40
+ - [Response](#response)
41
+ - [示例](#示例-9)
42
+ - [兼容性](#兼容性-9)
43
+ - [Headers](#headers)
44
+ - [示例](#示例-10)
45
+ - [兼容性](#兼容性-10)
46
+ - [AbortController](#abortcontroller)
47
+ - [示例](#示例-11)
48
+ - [兼容性](#兼容性-11)
49
+ - [EventTarget](#eventtarget)
50
+ - [示例](#示例-12)
51
+ - [兼容性](#兼容性-12)
52
+ - [XMLHttpRequest (小程序)](#xmlhttprequest-小程序)
53
+ - [示例](#示例-13)
54
+ - [兼容性](#兼容性-13)
55
+ - [WebSocket (小程序, 从1.1.0之后)](#websocket-小程序-从110之后)
56
+ - [示例](#示例-14)
57
+ - [兼容性](#兼容性-14)
58
+ - [自动导入](#自动导入)
59
+ - [UniApp \& Taro](#uniapp--taro)
60
+ - [Node.js](#nodejs)
61
+ - [开源协议](#开源协议)
62
+
63
+ ## 功能
64
+
65
+ - **TextEncoder**
66
+ - **TextDecoder**
67
+ - **Blob**
68
+ - **File**
69
+ - **FileReader**
70
+ - **URLSearchParams**
71
+ - **FormData**
72
+ - **fetch**
73
+ - **Headers**
74
+ - **Request**
75
+ - **Response**
76
+ - **AbortController**
77
+ - **EventTarget**
78
+ - **XMLHttpRequest (小程序)**
79
+ - **WebSocket (小程序, 从1.1.0之后)**
80
+
81
+ ## 安装
82
+
83
+ ```
84
+ npm install mphttpx
85
+ ```
86
+
87
+ ## 小程序支持情况
88
+
89
+ | 微信 | 支付宝 | 百度 | 抖音 | QQ | 快手 | 京东 | 小红书 |
90
+ |:---:|:------:|:----:|:---:|:--:|:----:|:---:|:------:|
91
+ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
92
+
93
+ 注意:在现代浏览器中,并不需要这些填充功能,在浏览器中从mphttpx导入的函数会直接返回浏览器本地的函数。
94
+
95
+ ## 使用
96
+
97
+ 注意:mphttpx中所有的模块都有一个与之对应的以字母P结尾的版本,两者的区别在于以字母P结尾的版本是polyfill的。
98
+
99
+ 举个例子:
100
+
101
+ ```javascript
102
+ // mphttpx不对globalThis做任何修改
103
+ import { TextEncoder } from "mphttpx"; // 优先返回全局对象,如果不存在则返回polyfill实现
104
+ import { TextEncoderP } from "mphttpx"; // 直接返回polyfill实现
105
+ ```
106
+
107
+ ### TextEncoder
108
+
109
+ #### 示例
110
+
111
+ ```javascript
112
+ import { TextEncoder } from "mphttpx";
113
+
114
+ const encoder = new TextEncoder();
115
+ const encoded = encoder.encode("€");
116
+
117
+ console.log(encoded); // Uint8Array(3) [226, 130, 172]
118
+ ```
119
+
120
+ #### 兼容性
121
+
122
+ 属性
123
+
124
+ | 属性 | 可用性 | 描述 |
125
+ | --------- | --------- | -------------|
126
+ | encoding | ✔ | utf-8 |
127
+
128
+ 方法
129
+
130
+ | 方法 | 可用性 | 描述 |
131
+ | ------- | --------- | -------------|
132
+ | encode(string) | ✔ |
133
+ | encodeInto(string, uint8Array) | ✔ |
134
+
135
+ ### TextDecoder
136
+
137
+ #### 示例
138
+
139
+ ```javascript
140
+ import { TextDecoder } from "mphttpx";
141
+
142
+ const utf8decoder = new TextDecoder(); // 默认 'utf-8'
143
+ const encodedText = new Uint8Array([240, 160, 174, 183]);
144
+
145
+ console.log(utf8decoder.decode(encodedText)); // 𠮷
146
+ ```
147
+
148
+ #### 兼容性
149
+
150
+ 属性
151
+
152
+ | 属性 | 可用性 | 描述 |
153
+ | --------- | --------- | -------------|
154
+ | encoding | ✔ | 仅utf-8 |
155
+ | fatal | ✔ |
156
+ | ignoreBOM | ✔ |
157
+
158
+ 方法
159
+
160
+ | 方法 | 可用性 | 描述 |
161
+ | ------- | --------- | -------------|
162
+ | decode() | ✔ |
163
+ | decode(buffer) | ✔ |
164
+ | decode(buffer, options) | ✔ |
165
+
166
+ ### Blob
167
+
168
+ #### 示例
169
+
170
+ 创建blob
171
+
172
+ ```javascript
173
+ import { Blob, fetch } from "mphttpx";
174
+
175
+ const obj = { hello: "world" };
176
+ const blob = new Blob([JSON.stringify(obj, null, 2)], {
177
+ type: "application/json",
178
+ });
179
+
180
+ const another_blob = new Blob(["Hello, World!"], {
181
+ type: "text/plain"
182
+ });
183
+
184
+ fetch("https://www.test.com/blob", {
185
+ method: "POST",
186
+ body: another_blob,
187
+ });
188
+ ```
189
+
190
+ 从blob提取数据
191
+
192
+ ```javascript
193
+ import { Blob, FileReader, fetch } from "mphttpx";
194
+
195
+ const blob = new Blob([JSON.stringify({ foo: "bar" })], {
196
+ type: "application/json",
197
+ });
198
+
199
+ const reader = new FileReader();
200
+ reader.addEventListener("loadend", () => {
201
+ // reader.result中包含了ArrayBuffer数据格式的内容
202
+ });
203
+ reader.readAsArrayBuffer(blob);
204
+
205
+ fetch("https://www.test.com/blob", {
206
+ method: "POST",
207
+ body: blob,
208
+ })
209
+ .then(r => r.blob())
210
+ .then(r => {
211
+ const reader2 = new FileReader();
212
+ reader2.onload = () => {
213
+ // reader2.result
214
+ }
215
+ reader2.readAsDataURL(r); // base64
216
+ });
217
+ ```
218
+
219
+ #### 兼容性
220
+
221
+ 属性
222
+
223
+ | 属性 | 可用性 | 描述 |
224
+ | --------- | --------- | -------------|
225
+ | size | ✔ |
226
+ | type | ✔ |
227
+
228
+ 方法
229
+
230
+ | 方法 | 可用性 | 描述 |
231
+ | ------- | --------- | -------------|
232
+ | arrayBuffer() | ✔ |
233
+ | bytes() | ✔ |
234
+ | slice() | ✔ |
235
+ | slice(start) | ✔ |
236
+ | slice(start, end) | ✔ |
237
+ | slice(start, end, contentType) | ✔ |
238
+ | stream() | ✖ |
239
+ | text() | ✔ |
240
+
241
+ ### File
242
+
243
+ #### 示例
244
+
245
+ ```javascript
246
+ import { File } from "mphttpx";
247
+
248
+ const file = new File(["foo"], "foo.txt", {
249
+ type: "text/plain",
250
+ });
251
+ ```
252
+
253
+ #### 兼容性
254
+
255
+ 属性
256
+
257
+ | 属性 | 可用性 | 描述 |
258
+ | --------- | --------- | -------------|
259
+ | lastModified | ✔ |
260
+ | name | ✔ |
261
+ | webkitRelativePath | ✖ |
262
+
263
+ ### FileReader
264
+
265
+ #### 示例
266
+
267
+ ```javascript
268
+ import { File, FileReader } from "mphttpx";
269
+
270
+ const file = new File([JSON.stringify({ foo: "bar" })], "test.json", {
271
+ type: "application/json",
272
+ });
273
+
274
+ // 读取file
275
+ const reader = new FileReader();
276
+ reader.onload = () => {
277
+ console.log(reader.result);
278
+ };
279
+ reader.readAsText(file);
280
+ ```
281
+
282
+ #### 兼容性
283
+
284
+ 属性
285
+
286
+ | 属性 | 可用性 | 描述 |
287
+ | --------- | --------- | -------------|
288
+ | error | ✔ |
289
+ | readyState | ✔ |
290
+ | result | ✔ |
291
+
292
+ 方法
293
+
294
+ | 方法 | 可用性 | 描述 |
295
+ | ------- | --------- | -------------|
296
+ | abort() | ✔ | 模拟实现 |
297
+ | readAsArrayBuffer() | ✔ |
298
+ | readAsBinaryString() | ✔ |
299
+ | readAsDataURL() | ✔ |
300
+ | readAsText() | ✔ | 仅utf-8 |
301
+
302
+ ### URLSearchParams
303
+
304
+ #### 示例
305
+
306
+ ```javascript
307
+ import { URLSearchParams, fetch } from "mphttpx";
308
+
309
+ const paramsString = "q=URLUtils.searchParams&topic=api";
310
+ const searchParams = new URLSearchParams(paramsString);
311
+
312
+ // 迭代搜索参数
313
+ for (const p of searchParams) {
314
+ console.log(p);
315
+ }
316
+
317
+ console.log(searchParams.has("topic")); // true
318
+ console.log(searchParams.has("topic", "fish")); // false
319
+ console.log(searchParams.get("topic") === "api"); // true
320
+ console.log(searchParams.getAll("topic")); // ["api"]
321
+ console.log(searchParams.get("foo") === null); // true
322
+ console.log(searchParams.append("topic", "webdev"));
323
+ console.log(searchParams.toString()); // "q=URLUtils.searchParams&topic=api&topic=webdev"
324
+ console.log(searchParams.set("topic", "More webdev"));
325
+ console.log(searchParams.toString()); // "q=URLUtils.searchParams&topic=More+webdev"
326
+ console.log(searchParams.delete("topic"));
327
+ console.log(searchParams.toString()); // "q=URLUtils.searchParams"
328
+
329
+ // GET
330
+ fetch("https://www.test.com/get" + `?${searchParams.toString()}`);
331
+
332
+ // POST
333
+ fetch("https://www.test.com/post", {
334
+ method: "POST",
335
+ body: searchParams,
336
+ });
337
+ ```
338
+
339
+ 搜索参数也可以通过对象构造
340
+
341
+ ```javascript
342
+ import { URLSearchParams } from "mphttpx";
343
+
344
+ const paramsObj = { foo: "bar", baz: "bar" };
345
+ const searchParams = new URLSearchParams(paramsObj);
346
+
347
+ console.log(searchParams.toString()); // "foo=bar&baz=bar"
348
+ console.log(searchParams.has("foo")); // true
349
+ console.log(searchParams.get("foo")); // "bar"
350
+ ```
351
+
352
+ #### 兼容性
353
+
354
+ 属性
355
+
356
+ | 属性 | 可用性 | 描述 |
357
+ | --------- | --------- | -------------|
358
+ | size | ✔ |
359
+
360
+ 方法
361
+
362
+ | 方法 | 可用性 | 描述 |
363
+ | ------- | --------- | -------------|
364
+ | append(name, value) | ✔ |
365
+ | delete(name) | ✔ |
366
+ | delete(name, value) | ✔ |
367
+ | entries() | ✔ |
368
+ | forEach(callback) | ✔ |
369
+ | forEach(callback, thisArg) | ✔ |
370
+ | get(name) | ✔ |
371
+ | getAll(name) | ✔ |
372
+ | has(name) | ✔ |
373
+ | has(name, value) | ✔ |
374
+ | keys() | ✔ |
375
+ | set(name, value) | ✔ |
376
+ | sort() | ✔ |
377
+ | toString() | ✔ |
378
+ | values() | ✔ |
379
+
380
+ ### FormData
381
+
382
+ #### 示例
383
+
384
+ ```javascript
385
+ import { FormData, fetch } from "mphttpx";
386
+
387
+ const formData = new FormData();
388
+ formData.append("username", "Chris");
389
+
390
+ const file = new File(["Hello, World!"], "file.txt", {
391
+ type: "text/plain",
392
+ });
393
+ formData.append("file", file);
394
+
395
+ fetch("https://www.test.com/formdata", {
396
+ method: "POST",
397
+ body: formData,
398
+ });
399
+ ```
400
+
401
+ #### 兼容性
402
+
403
+ 构造函数
404
+
405
+ | 构造函数 | 可用性 | 描述 |
406
+ | ----------- | --------- | -------------|
407
+ | new FormData() | ✔ |
408
+ | new FormData(form) | ✖ |
409
+ | new FormData(form, submitter) | ✖ |
410
+
411
+ 方法
412
+
413
+ | 方法 | 可用性 | 描述 |
414
+ | ------- | --------- | -------------|
415
+ | append(name, value) | ✔ |
416
+ | append(name, value, filename) | ✔ |
417
+ | delete(name) | ✔ |
418
+ | entries() | ✔ |
419
+ | get(name) | ✔ |
420
+ | getAll(name) | ✔ |
421
+ | has(name) | ✔ |
422
+ | keys() | ✔ |
423
+ | set(name, value) | ✔ |
424
+ | set(name, value, filename) | ✔ |
425
+ | values() | ✔ |
426
+
427
+ ### fetch
428
+
429
+ #### 示例
430
+
431
+ ```javascript
432
+ import { fetch } from "mphttpx";
433
+
434
+ fetch("http://example.com/movies.json")
435
+ .then((response) => response.json())
436
+ .then((data) => console.log(data));
437
+ ```
438
+
439
+ 通过fetch发送JSON数据
440
+
441
+ ```javascript
442
+ import { fetch } from "mphttpx";
443
+
444
+ const data = { username: "example" };
445
+
446
+ fetch("https://example.com/profile", {
447
+ method: "POST", // 或 'PUT'
448
+ headers: {
449
+ "Content-Type": "application/json",
450
+ },
451
+ body: JSON.stringify(data),
452
+ })
453
+ .then((response) => response.json())
454
+ .then((data) => {
455
+ console.log("Success:", data);
456
+ })
457
+ .catch((error) => {
458
+ console.error("Error:", error);
459
+ });
460
+ ```
461
+
462
+ 上传文件
463
+
464
+ ```javascript
465
+ import { fetch, File, FormData } from "mphttpx";
466
+
467
+ const formData = new FormData();
468
+
469
+ formData.append("username", "abc123");
470
+ formData.append("file", new File(["foo"], "foo.txt", { type: "text/plain" }));
471
+
472
+ fetch("https://example.com/profile/avatar", {
473
+ method: "PUT",
474
+ body: formData,
475
+ })
476
+ .then((response) => response.json())
477
+ .then((result) => {
478
+ console.log("Success:", result);
479
+ })
480
+ .catch((error) => {
481
+ console.error("Error:", error);
482
+ });
483
+ ```
484
+
485
+ 注意:fetch基于下层XMLHttpRequest实现,且这个下层实现是可以替换的。
486
+
487
+ ```javascript
488
+ import { setXMLHttpRequest } from "mphttpx";
489
+ setXMLHttpRequest(another_XMLHttpRequest); // 自定义XMLHttpRequest实现
490
+ ```
491
+
492
+ | 方法 | 可用性 | 描述 |
493
+ | ------- | --------- | -------------|
494
+ | fetch(resource) | ✔ |
495
+ | fetch(resource, options) | ✔ |
496
+
497
+ #### 兼容性
498
+
499
+ 参考下方Request
500
+
501
+ ### Request
502
+
503
+ #### 示例
504
+
505
+ ```javascript
506
+ import { fetch, Request } from "mphttpx";
507
+
508
+ const request = new Request("https://www.mozilla.org/favicon.ico");
509
+
510
+ const url = request.url;
511
+ const method = request.method;
512
+ const credentials = request.credentials;
513
+
514
+ fetch(request)
515
+ .then((response) => response.blob())
516
+ .then((blob) => {
517
+ console.log(blob);
518
+ });
519
+ ```
520
+
521
+ ```javascript
522
+ import { fetch, Request } from "mphttpx";
523
+
524
+ const request = new Request("https://example.com", {
525
+ method: "POST",
526
+ body: '{"foo": "bar"}',
527
+ });
528
+
529
+ const url = request.url;
530
+ const method = request.method;
531
+ const credentials = request.credentials;
532
+ const bodyUsed = request.bodyUsed;
533
+
534
+ fetch(request)
535
+ .then((response) => {
536
+ if (response.status === 200) {
537
+ return response.json();
538
+ } else {
539
+ throw new Error("Something went wrong on API server!");
540
+ }
541
+ })
542
+ .then((response) => {
543
+ console.debug(response);
544
+ // …
545
+ })
546
+ .catch((error) => {
547
+ console.error(error);
548
+ });
549
+ ```
550
+
551
+ #### 兼容性
552
+
553
+ 属性
554
+
555
+ | 属性 | 可用性 | 描述 |
556
+ | --------- | --------- | -------------|
557
+ | body | ✖ |
558
+ | bodyUsed | ✔ |
559
+ | cache | ✔ |
560
+ | credentials | ✔ |
561
+ | destination | ✖ |
562
+ | headers | ✔ |
563
+ | integrity | ✖ |
564
+ | keepalive | ✖ |
565
+ | method | ✔ |
566
+ | mode | ✖ |
567
+ | redirect | ✖ |
568
+ | referrer | ✖ |
569
+ | referrerPolicy | ✖ |
570
+ | signal | ✔ |
571
+ | url | ✔ |
572
+
573
+ 方法
574
+
575
+ | 方法 | 可用性 | 描述 |
576
+ | ------- | --------- | -------------|
577
+ | arrayBuffer() | ✔ |
578
+ | blob() | ✔ |
579
+ | bytes() | ✔ |
580
+ | clone() | ✔ |
581
+ | formData() | ✔ |
582
+ | json() | ✔ |
583
+ | text() | ✔ |
584
+
585
+ ### Response
586
+
587
+ #### 示例
588
+
589
+ ```javascript
590
+ import { Response, Blob, fetch } from "mphttpx";
591
+
592
+ const myBlob = new Blob();
593
+ const myOptions = { status: 200, statusText: "SuperSmashingGreat!" };
594
+ const myResponse = new Response(myBlob, myOptions);
595
+ ```
596
+
597
+ #### 兼容性
598
+
599
+ 属性
600
+
601
+ | 属性 | 可用性 | 描述 |
602
+ | --------- | --------- | -------------|
603
+ | body | ✖ |
604
+ | bodyUsed | ✔ |
605
+ | headers | ✔ |
606
+ | ok | ✔ |
607
+ | redirected | ✖ |
608
+ | status | ✔ |
609
+ | statusText | ✔ |
610
+ | type | ✖ |
611
+ | url | ✔ |
612
+
613
+ 方法
614
+
615
+ | 方法 | 可用性 | 描述 |
616
+ | ------- | --------- | -------------|
617
+ | arrayBuffer() | ✔ |
618
+ | blob() | ✔ |
619
+ | bytes() | ✔ |
620
+ | clone() | ✔ |
621
+ | formData() | ✔ |
622
+ | json() | ✔ |
623
+ | text() | ✔ |
624
+
625
+ ### Headers
626
+
627
+ #### 示例
628
+
629
+ ```javascript
630
+ import { Headers, fetch } from "mphttpx";
631
+
632
+ const myHeaders = new Headers();
633
+
634
+ myHeaders.append("Content-Type", "text/plain");
635
+ myHeaders.get("Content-Type"); // 应当返回'text/plain'
636
+
637
+ fetch("https://www.test.com/headers", {
638
+ headers: myHeaders,
639
+ });
640
+ ```
641
+
642
+ 通过传递数组的数组或普通对象也可进行构造:
643
+
644
+ ```javascript
645
+ import { Headers } from "mphttpx";
646
+
647
+ let myHeaders = new Headers({
648
+ "Content-Type": "text/plain",
649
+ });
650
+
651
+ // 或:使用数组的数组:
652
+ myHeaders = new Headers([["Content-Type", "text/plain"]]);
653
+
654
+ myHeaders.get("Content-Type"); // 应当返回'text/plain'
655
+ ```
656
+
657
+ #### 兼容性
658
+
659
+ 方法
660
+
661
+ | 方法 | 可用性 | 描述 |
662
+ | ------- | --------- | -------------|
663
+ | append(name, value) | ✔ |
664
+ | delete(name) | ✔ |
665
+ | entries() | ✔ |
666
+ | forEach(callbackFn) | ✔ |
667
+ | forEach(callbackFn, thisArg) | ✔ |
668
+ | get(name) | ✔ |
669
+ | getSetCookie() | ✔ |
670
+ | has(name) | ✔ |
671
+ | keys() | ✔ |
672
+ | set(name, value) | ✔ |
673
+ | values() | ✔ |
674
+
675
+ ### AbortController
676
+
677
+ #### 示例
678
+
679
+ ```javascript
680
+ import { AbortController, fetch } from "mphttpx";
681
+
682
+ const controller = new AbortController();
683
+
684
+ fetch("https://www.test.com/abort", {
685
+ signal: controller.signal,
686
+ });
687
+ ```
688
+
689
+ ```javascript
690
+ import { AbortController, AbortSignal, Request, fetch } from "mphttpx";
691
+
692
+ async function get() {
693
+ const controller = new AbortController();
694
+ const request = new Request("https://example.org/get", {
695
+ signal: controller.signal,
696
+ });
697
+
698
+ const response = await fetch(request);
699
+ controller.abort();
700
+ // 下一行将会抛出`AbortError`异常
701
+ const text = await response.text();
702
+ console.log(text);
703
+ }
704
+ ```
705
+
706
+ #### 兼容性
707
+
708
+ AbortController属性
709
+
710
+ | 属性 | 可用性 | 描述 |
711
+ | --------- | --------- | -------------|
712
+ | signal | ✔ |
713
+
714
+ AbortController方法
715
+
716
+ | 方法 | 可用性 | 描述 |
717
+ | ------- | --------- | -------------|
718
+ | abort() | ✔ |
719
+ | abort(reason) | ✔ |
720
+
721
+ AbortSignal属性
722
+
723
+ | 属性 | 可用性 | 描述 |
724
+ | --------- | --------- | -------------|
725
+ | aborted | ✔ |
726
+ | reason | ✔ |
727
+
728
+ AbortSignal方法
729
+
730
+ | 方法 | 可用性 | 描述 |
731
+ | ------- | --------- | -------------|
732
+ | throwIfAborted() | ✔ |
733
+
734
+ ### EventTarget
735
+
736
+ #### 示例
737
+
738
+ ```javascript
739
+ import { EventTarget, Event, CustomEvent } from "mphttpx";
740
+
741
+ const target = new EventTarget();
742
+
743
+ target.addEventListener("foo", function (evt) {
744
+ console.log(evt);
745
+ });
746
+
747
+ const evt = new Event("foo");
748
+ target.dispatchEvent(evt);
749
+
750
+ target.addEventListener("animalfound", function (evt) {
751
+ console.log(evt.detail.name);
752
+ });
753
+
754
+ const catFound = new CustomEvent("animalfound", {
755
+ detail: {
756
+ name: "cat",
757
+ },
758
+ });
759
+ target.dispatchEvent(catFound);
760
+ ```
761
+
762
+ #### 兼容性
763
+
764
+ 方法
765
+
766
+ | 方法 | 可用性 | 描述 |
767
+ | ------- | --------- | -------------|
768
+ | addEventListener(type, listener) | ✔ |
769
+ | addEventListener(type, listener, options) | ✔ |
770
+ | addEventListener(type, listener, useCapture) | ✔ |
771
+ | dispatchEvent(event) | ✔ |
772
+ | removeEventListener(type, listener) | ✔ |
773
+ | removeEventListener(type, listener, options) | ✔ |
774
+ | removeEventListener(type, listener, useCapture) | ✔ |
775
+
776
+ ### XMLHttpRequest (小程序)
777
+
778
+ #### 示例
779
+
780
+ GET
781
+
782
+ ```javascript
783
+ import { XMLHttpRequest } from "mphttpx";
784
+
785
+ const xhr = new XMLHttpRequest();
786
+ xhr.open("GET", "https://example.com/server?foo=bar&lorem=ipsum");
787
+
788
+ xhr.onload = () => {
789
+ // 请求完成。在此处理业务。
790
+ };
791
+
792
+ xhr.send();
793
+ ```
794
+
795
+ POST
796
+
797
+ ```javascript
798
+ import { XMLHttpRequest } from "mphttpx";
799
+
800
+ const xhr = new XMLHttpRequest();
801
+ xhr.open("POST", "https://example.com/server");
802
+
803
+ // 在请求时携带合适的头信息
804
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
805
+
806
+ xhr.onreadystatechange = () => {
807
+ // 当状态变化时调用函数
808
+ if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
809
+ // 请求完成。在此处理业务。
810
+ }
811
+ };
812
+
813
+ xhr.send(JSON.stringify({ foo: "bar", lorem: "ipsum" }));
814
+ ```
815
+
816
+ #### 兼容性
817
+
818
+ 属性
819
+
820
+ | 属性 | 可用性 | 描述 |
821
+ | --------- | --------- | -------------|
822
+ | readyState | ✔ | 2, 3: 模拟实现 |
823
+ | response | ✔ |
824
+ | responseText | ✔ |
825
+ | responseType | ✔ | 不支持`"document"` |
826
+ | responseURL | ✔ | `responseURL`将原样返回请求中的URL地址 |
827
+ | responseXML | ✖ |
828
+ | status | ✔ |
829
+ | statusText | ✔ |
830
+ | timeout | ✔ | 该值必须小于小程序的默认超时时间 |
831
+ | upload | ✔ | 模拟实现 |
832
+ | withCredentials | ✖ |
833
+
834
+ 方法
835
+
836
+ | 方法 | 可用性 | 描述 |
837
+ | ------- | --------- | -------------|
838
+ | abort() | ✔ |
839
+ | getAllResponseHeaders() | ✔ |
840
+ | getResponseHeader(headerName) | ✔ |
841
+ | open(method, url) | ✔ |
842
+ | open(method, url, async) | ✔ |
843
+ | open(method, url, async, user) | ✔ |
844
+ | open(method, url, async, user, password) | ✔ |
845
+ | overrideMimeType(mimeType) | ✖ |
846
+ | send() | ✔ |
847
+ | send(body) | ✔ |
848
+ | setRequestHeader(header, value) | ✔ |
849
+
850
+ ### WebSocket (小程序, 从1.1.0之后)
851
+
852
+ #### 示例
853
+
854
+ ```javascript
855
+ import { WebSocket } from "mphttpx";
856
+
857
+ // 创建WebSocket连接
858
+ const socket = new WebSocket("wss://example.com:8080");
859
+
860
+ // 将二进制类型从"blob"改为"arraybuffer"
861
+ socket.binaryType = "arraybuffer";
862
+
863
+ // 监听消息
864
+ socket.addEventListener("message", (event) => {
865
+ if (event.data instanceof ArrayBuffer) {
866
+ // 二进制帧
867
+ const view = new DataView(event.data);
868
+ console.log(view.getInt32(0));
869
+ } else {
870
+ // 文本帧
871
+ console.log(event.data);
872
+ }
873
+ });
874
+ ```
875
+
876
+ #### 兼容性
877
+
878
+ 属性
879
+
880
+ | 属性 | 可用性 | 描述 |
881
+ | --------- | --------- | -------------|
882
+ | binaryType | ✔ |
883
+ | bufferedAmount | ✖ |
884
+ | extensions | ✖ |
885
+ | protocol | ✔ |
886
+ | readyState | ✔ |
887
+ | url | ✔ |
888
+
889
+ 方法
890
+
891
+ | 方法 | 可用性 | 描述 |
892
+ | ------- | --------- | -------------|
893
+ | close() | ✔ |
894
+ | close(code) | ✔ |
895
+ | close(code, reason) | ✔ |
896
+ | send(data) | ✔ |
897
+
898
+ ## 自动导入
899
+
900
+ 查看[unplugin-auto-import][2]获取更多信息。
901
+
902
+ ```javascript
903
+ // 仅参考
904
+ AutoImport({
905
+ // 其他配置
906
+
907
+ imports: [
908
+ // 其他导入
909
+
910
+ {
911
+ "mphttpx": [
912
+ "TextEncoder",
913
+ "TextDecoder",
914
+
915
+ "Blob",
916
+ "File",
917
+ "FileReader",
918
+
919
+ "URLSearchParams",
920
+ "FormData",
921
+
922
+ "fetch",
923
+ "Headers",
924
+ "Request",
925
+ "Response",
926
+
927
+ "AbortController",
928
+ "AbortSignal",
929
+
930
+ "EventTarget",
931
+ "Event",
932
+ "CustomEvent",
933
+
934
+ "XMLHttpRequest", // 小程序
935
+ "WebSocket", // 小程序
936
+ ],
937
+ },
938
+
939
+ // 其他导入
940
+ ],
941
+
942
+ // 其他配置
943
+ });
944
+ ```
945
+
946
+ 注意(UniApp开发者):如果你的项目是通过HBuilderX以老式Vue2为模板创建的,尝试安装老版本的unplugin-auto-import以支持CMD模块,比如0.16.7版本。
947
+
948
+ ## UniApp & Taro
949
+
950
+ ```javascript
951
+ import { setRequest } from "mphttpx";
952
+ import { setConnectSocket } from "mphttpx";
953
+
954
+ setRequest(uni.request);
955
+ // setRequest(Taro.request);
956
+
957
+ setConnectSocket(uni.connectSocket);
958
+ // setConnectSocket(Taro.connectSocket);
959
+ ```
960
+
961
+ 注意:使用UniApp或Taro时,如果`fetch`, `XMLHttpRequest`或`WebSocket`无法正常工作,尝试显式设置request/connectSocket函数。
962
+
963
+ ## Node.js
964
+
965
+ ```bash
966
+ npm install xhr2
967
+ ```
968
+
969
+ ```javascript
970
+ import XMLHttpRequest from "xhr2";
971
+ import { setXMLHttpRequest } from "mphttpx";
972
+
973
+ setXMLHttpRequest(XMLHttpRequest);
974
+ ```
975
+
976
+ ## 开源协议
977
+
978
+ MIT
979
+
980
+ [0]: https://github.com/eligrey/Blob.js
981
+ [1]: https://github.com/github/fetch
982
+ [2]: https://www.npmjs.com/package/unplugin-auto-import