@tarojs/plugin-http 3.8.0-canary.0 → 3.8.0-canary.1

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/LICENSE CHANGED
@@ -158,3 +158,17 @@ MIT (stencil-vue2-output-target):
158
158
  The following files embed [stencil-vue2-output-target](https://github.com/diondree/stencil-vue2-output-target) MIT:
159
159
  `/packages/taro-components-library-vue2/src/vue-component-lib/utils.ts`
160
160
  See `/LICENSE` for details of the license.
161
+
162
+ ==================
163
+
164
+ MIT (weui):
165
+ The following files embed [stencil-vue2-output-target](https://github.com/Tencent/weui) MIT:
166
+ `/packages/taro-components/src/components/*.scss`
167
+ See `/LICENSE.txt` for details of the license.
168
+
169
+ ==================
170
+
171
+ Apache-2.0 (intersection-observer):
172
+ The following files embed [intersection-observer](https://github.com/GoogleChromeLabs/intersection-observer) Apache-2.0:
173
+ `/packages/taro-api/src/polyfill/intersection-observer.ts`
174
+ See `/LICENSE.txt` for details of the license.
package/dist/runtime.d.ts CHANGED
@@ -58,7 +58,10 @@ declare class XMLHttpRequest extends Events {
58
58
  // 欺骗一些库让其认为是原生的xhr
59
59
  static toString(): string;
60
60
  toString(): string;
61
- // 事件
61
+ // 事件正常流转: loadstart => progress(可能多次) => load => loadend
62
+ // error 流转: loadstart => error => loadend
63
+ // abort 流转: loadstart => abort => loadend
64
+ // web在线测试: https://developer.mozilla.org/zh-CN/play
62
65
  /** 当 request 被停止时触发,例如当程序调用 XMLHttpRequest.abort() 时 */
63
66
  onabort: ((e: XMLHttpRequestEvent) => void) | null;
64
67
  /** 当 request 遭遇错误时触发 */
package/dist/runtime.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { parseUrl, Events, createEvent, window, document } from '@tarojs/runtime';
2
2
  export { document } from '@tarojs/runtime';
3
- import { isString, isFunction, isWebPlatform } from '@tarojs/shared';
4
3
  import { setStorage, getStorageSync, request } from '@tarojs/taro';
4
+ import { isString, isFunction } from '@tarojs/shared';
5
5
 
6
6
  /******************************************************************************
7
7
  Copyright (c) Microsoft Corporation.
@@ -17,7 +17,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
17
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
18
  PERFORMANCE OF THIS SOFTWARE.
19
19
  ***************************************************************************** */
20
- /* global Reflect, Promise */
20
+ /* global Reflect, Promise, SuppressedError, Symbol */
21
21
 
22
22
 
23
23
  function __classPrivateFieldGet(receiver, state, kind, f) {
@@ -31,7 +31,12 @@ function __classPrivateFieldSet(receiver, state, value, kind, f) {
31
31
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
32
32
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
33
33
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
34
- }
34
+ }
35
+
36
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
37
+ var e = new Error(message);
38
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
39
+ };
35
40
 
36
41
  var _Cookie_map;
37
42
  const STORAGE_KEY = 'PAGE_COOKIE';
@@ -357,20 +362,20 @@ function createXMLHttpRequestEvent(event, target, loaded) {
357
362
  const e = createEvent(event);
358
363
  try {
359
364
  Object.defineProperties(e, {
360
- 'currentTarget': {
365
+ currentTarget: {
361
366
  enumerable: true,
362
367
  value: target
363
368
  },
364
- 'target': {
369
+ target: {
365
370
  enumerable: true,
366
371
  value: target
367
372
  },
368
- 'loaded': {
373
+ loaded: {
369
374
  enumerable: true,
370
375
  value: loaded || 0
371
376
  },
372
377
  // 读 Content-Range 字段,目前来说作用不大,先和 loaded 保持一致
373
- 'total': {
378
+ total: {
374
379
  enumerable: true,
375
380
  value: loaded || 0
376
381
  }
@@ -406,7 +411,10 @@ class XMLHttpRequest extends Events {
406
411
  _XMLHttpRequest_timeout.set(this, void 0);
407
412
  _XMLHttpRequest_withCredentials.set(this, void 0);
408
413
  _XMLHttpRequest_requestTask.set(this, void 0);
409
- // 事件
414
+ // 事件正常流转: loadstart => progress(可能多次) => load => loadend
415
+ // error 流转: loadstart => error => loadend
416
+ // abort 流转: loadstart => abort => loadend
417
+ // web在线测试: https://developer.mozilla.org/zh-CN/play
410
418
  /** 当 request 被停止时触发,例如当程序调用 XMLHttpRequest.abort() 时 */
411
419
  this.onabort = null;
412
420
  /** 当 request 遭遇错误时触发 */
@@ -502,15 +510,17 @@ class XMLHttpRequest extends Events {
502
510
  }
503
511
  }
504
512
  getAllResponseHeaders() {
505
- if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f"))
513
+ if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")) {
506
514
  return '';
515
+ }
507
516
  return Object.keys(__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f"))
508
517
  .map((key) => `${key}: ${__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")[key]}`)
509
518
  .join('\r\n');
510
519
  }
511
520
  getResponseHeader(name) {
512
- if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f"))
521
+ if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")) {
513
522
  return null;
523
+ }
514
524
  // 处理大小写不敏感
515
525
  const key = Object.keys(__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")).find((item) => item.toLowerCase() === name.toLowerCase());
516
526
  const value = key ? __classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")[key] : null;
@@ -577,6 +587,7 @@ _XMLHttpRequest_method = new WeakMap(), _XMLHttpRequest_url = new WeakMap(), _XM
577
587
  // 头信息
578
588
  const header = Object.assign({}, __classPrivateFieldGet(this, _XMLHttpRequest_header, "f"));
579
589
  // https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
590
+ // @ts-ignore
580
591
  header.cookie = window.document.$$cookie;
581
592
  if (!this.withCredentials) {
582
593
  // 不同源,要求 withCredentials 为 true 才携带 cookie
@@ -606,7 +617,7 @@ _XMLHttpRequest_method = new WeakMap(), _XMLHttpRequest_url = new WeakMap(), _XM
606
617
  __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.HEADERS_RECEIVED);
607
618
  if (ENABLE_COOKIE) {
608
619
  // 处理 set-cookie
609
- const setCookieStr = header['Set-Cookie'];
620
+ const setCookieStr = this.getResponseHeader('set-cookie');
610
621
  if (setCookieStr && typeof setCookieStr === 'string') {
611
622
  let start = 0;
612
623
  let startSplit = 0;
@@ -634,17 +645,40 @@ _XMLHttpRequest_method = new WeakMap(), _XMLHttpRequest_url = new WeakMap(), _XM
634
645
  // 处理返回数据
635
646
  if (data) {
636
647
  __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.LOADING);
637
- const loadstartEvent = createXMLHttpRequestEvent('loadstart', this, header['Content-Length']);
648
+ const contentLength = Number(this.getResponseHeader('content-length') || 0);
649
+ const loadstartEvent = createXMLHttpRequestEvent('loadstart', this, contentLength);
638
650
  this.trigger('loadstart', loadstartEvent);
639
651
  isFunction(this.onloadstart) && this.onloadstart(loadstartEvent);
640
652
  __classPrivateFieldSet(this, _XMLHttpRequest_response, data, "f");
641
- const loadEvent = createXMLHttpRequestEvent('load', this, header['Content-Length']);
653
+ const loadEvent = createXMLHttpRequestEvent('load', this, contentLength);
642
654
  this.trigger('load', loadEvent);
643
655
  isFunction(this.onload) && this.onload(loadEvent);
644
656
  }
645
657
  }, _XMLHttpRequest_requestFail = function _XMLHttpRequest_requestFail(err) {
658
+ // 微信小程序,无论接口返回200还是其他,响应无论是否有错误,都会进入 success 回调;只有类似超时这种请求错误才会进入 fail 回调
659
+ //
660
+ /**
661
+ * 阿里系小程序,接口返回非200状态码,会进入 fail 回调, 此时 err 对象结构如下(当错误码为 14 或 19 时,会多返回 status、data、headers。可通过这些字段获取服务端相关错误信息):
662
+ {
663
+ data: "{\"code\": 401,\"msg\":\"登录过期,请重新登录\"}"
664
+ error: 19
665
+ errorMessage: "http status error"
666
+ headers: {date: 'Mon, 14 Aug 2023 08:54:58 GMT', content-type: 'application/json;charset=UTF-8', content-length: '52', connection: 'close', access-control-allow-credentials: 'true', …}
667
+ originalData: "{\"code\": 401,\"msg\":\"登录过期,请重新登录\"}"
668
+ status: 401
669
+ }
670
+ */
671
+ // 统一行为,能正常响应的,都算 success.
672
+ if (err.status) {
673
+ __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestSuccess).call(this, {
674
+ data: err,
675
+ statusCode: err.status,
676
+ header: err.headers
677
+ });
678
+ return;
679
+ }
646
680
  __classPrivateFieldSet(this, _XMLHttpRequest_status, 0, "f");
647
- __classPrivateFieldSet(this, _XMLHttpRequest_statusText, err.errMsg, "f");
681
+ __classPrivateFieldSet(this, _XMLHttpRequest_statusText, err.errMsg || err.errorMessage, "f");
648
682
  const errorEvent = createXMLHttpRequestEvent('error', this, 0);
649
683
  this.trigger('error', errorEvent);
650
684
  isFunction(this.onerror) && this.onerror(errorEvent);
@@ -652,7 +686,8 @@ _XMLHttpRequest_method = new WeakMap(), _XMLHttpRequest_url = new WeakMap(), _XM
652
686
  __classPrivateFieldSet(this, _XMLHttpRequest_requestTask, null, "f");
653
687
  __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.DONE);
654
688
  if (__classPrivateFieldGet(this, _XMLHttpRequest_status, "f")) {
655
- const loadendEvent = createXMLHttpRequestEvent('loadend', this, __classPrivateFieldGet(this, _XMLHttpRequest_header, "f")['Content-Length']);
689
+ const contentLength = Number(this.getResponseHeader('content-length') || 0);
690
+ const loadendEvent = createXMLHttpRequestEvent('loadend', this, contentLength);
656
691
  this.trigger('loadend', loadendEvent);
657
692
  isFunction(this.onloadend) && this.onloadend(loadendEvent);
658
693
  }
@@ -663,7 +698,7 @@ XMLHttpRequest.HEADERS_RECEIVED = 2;
663
698
  XMLHttpRequest.LOADING = 3;
664
699
  XMLHttpRequest.DONE = 4;
665
700
 
666
- if (!isWebPlatform()) {
701
+ if (process.env.TARO_PLATFORM !== 'web') {
667
702
  if (ENABLE_COOKIE) {
668
703
  const _cookie = createCookieInstance();
669
704
  Object.defineProperties(document, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tarojs/plugin-http",
3
- "version": "3.8.0-canary.0",
3
+ "version": "3.8.0-canary.1",
4
4
  "description": "Taro 小程序端支持使用 web 请求 的插件",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -23,12 +23,12 @@
23
23
  },
24
24
  "homepage": "https://github.com/NervJS/taro#readme",
25
25
  "dependencies": {
26
- "@tarojs/runtime": "3.8.0-canary.0",
27
- "@tarojs/service": "3.8.0-canary.0",
28
- "@tarojs/shared": "3.8.0-canary.0"
26
+ "@tarojs/runtime": "3.8.0-canary.1",
27
+ "@tarojs/shared": "3.8.0-canary.1",
28
+ "@tarojs/service": "3.8.0-canary.1"
29
29
  },
30
30
  "devDependencies": {
31
- "@rollup/plugin-json": "^4.1.0",
31
+ "@rollup/plugin-json": "^6.1.0",
32
32
  "@rollup/plugin-node-resolve": "^15.0.1",
33
33
  "jest": "^29.3.1",
34
34
  "jest-cli": "^29.3.1",
@@ -37,13 +37,13 @@
37
37
  "rollup-plugin-node-externals": "^5.0.0",
38
38
  "rollup-plugin-ts": "^3.0.2",
39
39
  "ts-jest": "^29.0.5",
40
- "tslib": "^2.5.0",
40
+ "tslib": "^2.6.2",
41
41
  "typescript": "^4.7.4"
42
42
  },
43
43
  "scripts": {
44
44
  "dev": "rollup -c -w --bundleConfigAsCjs",
45
45
  "build": "rollup -c --bundleConfigAsCjs",
46
46
  "test": "jest",
47
- "test:ci": "jest --ci -i --coverage false"
47
+ "test:ci": "jest --ci -i --coverage --silent"
48
48
  }
49
49
  }
@@ -85,5 +85,4 @@ describe('cookie', () => {
85
85
  expect(cookie.getCookie(url1)).toBe('aaa=bbb; abc=cba; ggg=hhh; kkk=lll; ooo=ppp')
86
86
  expect(cookie.getCookie(url4)).toBe('aaa=bbb; abc=cba; ggg=hhh; kkk=lll; mmm=nnn')
87
87
  })
88
-
89
88
  })
@@ -3,9 +3,8 @@ describe('DOM', () => {
3
3
  const runtime = require('../../dist/runtime')
4
4
  const document = runtime.document
5
5
  global.document = runtime.document
6
-
7
- describe('document', () => {
8
6
 
7
+ describe('document', () => {
9
8
  it('document setCookie', async () => {
10
9
  expect(document.cookie).toBe('')
11
10
  document.cookie = 'aaa=1111-2222-33-444-abcdefgasd; path=/; expires=Mon, 18 Jan 2038 19:14:07 GMT; secure;'
@@ -15,6 +14,5 @@ describe('DOM', () => {
15
14
  'aaa=1111-2222-33-444-abcdefgasd; bbb=23123-aswe-4a7a-a740-f55dfd296b1d; ccc=69asd3d81234668942'
16
15
  )
17
16
  })
18
-
19
17
  })
20
18
  })
@@ -0,0 +1,101 @@
1
+ import { window } from '@tarojs/runtime'
2
+ import { request, RequestTask } from '@tarojs/taro'
3
+
4
+ import { XMLHttpRequest, XMLHttpRequestEvent } from '../../dist/runtime'
5
+
6
+ jest.mock('@tarojs/taro', () => {
7
+ return {
8
+ request: jest.fn(),
9
+ }
10
+ })
11
+
12
+ const requestMock = jest.mocked(request)
13
+
14
+ describe('XMLHttpRequest', () => {
15
+ it('大写header key', async () => {
16
+ const data = 'success'
17
+ // 模拟实现 request 函数
18
+ requestMock.mockImplementation((opt) => {
19
+ if (opt.success) {
20
+ const header = { 'Content-Length': data.length.toString() }
21
+ opt.success({ data: data as any, header, statusCode: 200, errMsg: '' })
22
+ }
23
+ if (opt.complete) {
24
+ opt.complete({ errMsg: '' })
25
+ }
26
+ return {} as RequestTask<any>
27
+ })
28
+ // 发起请求
29
+ const xhr = new XMLHttpRequest()
30
+ xhr.open('GET', 'localhost')
31
+ const req = new Promise<XMLHttpRequestEvent>((resolve, reject) => {
32
+ xhr.addEventListener('load', resolve)
33
+ xhr.addEventListener('error', reject)
34
+ })
35
+ xhr.send('')
36
+ await req
37
+ // 检查是否能正常读取大写的header
38
+ expect(xhr.status).toBe(200)
39
+ expect(data.length).toBeGreaterThan(0)
40
+ expect(xhr.getResponseHeader('Content-length')).toBe(data.length.toString())
41
+ expect(xhr.getResponseHeader('content-length')).toBe(data.length.toString())
42
+ expect(xhr.getResponseHeader('Content-Length')).toBe(data.length.toString())
43
+ })
44
+ it('小写header key', async () => {
45
+ const data = 'success'
46
+ // 模拟实现 request 函数
47
+ requestMock.mockImplementation((opt) => {
48
+ if (opt.success) {
49
+ const header = { 'content-length': data.length.toString() }
50
+ opt.success({ data: data as any, header, statusCode: 200, errMsg: '' })
51
+ }
52
+ if (opt.complete) {
53
+ opt.complete({ errMsg: '' })
54
+ }
55
+ return {} as RequestTask<any>
56
+ })
57
+ const xhr = new XMLHttpRequest()
58
+ xhr.open('GET', 'localhost')
59
+ const req = new Promise<XMLHttpRequestEvent>((resolve, reject) => {
60
+ xhr.addEventListener('load', resolve)
61
+ xhr.addEventListener('error', reject)
62
+ })
63
+ xhr.send('')
64
+ await req
65
+ // 检查是否能成功读取小写的header
66
+ expect(xhr.status).toBe(200)
67
+ expect(xhr.responseText).toBe(data)
68
+ expect(xhr.getResponseHeader('Content-length')).toBe(data.length.toString())
69
+ expect(xhr.getResponseHeader('content-length')).toBe(data.length.toString())
70
+ expect(xhr.getResponseHeader('Content-Length')).toBe(data.length.toString())
71
+ })
72
+
73
+ it('set-cookie', async () => {
74
+ const data = 'success'
75
+ // 模拟实现 request 函数
76
+ requestMock.mockImplementation((opt) => {
77
+ if (opt.success) {
78
+ const header = { 'set-cookie': 'aaa=bbb; domain=taro.com' }
79
+ opt.success({ data: data as any, header, statusCode: 200, errMsg: '' })
80
+ }
81
+ if (opt.complete) {
82
+ opt.complete({ errMsg: '' })
83
+ }
84
+ return {} as RequestTask<any>
85
+ })
86
+ // 发送一个请求
87
+ const xhr = new XMLHttpRequest()
88
+ xhr.open('GET', 'localhost')
89
+ const req = new Promise<XMLHttpRequestEvent>((resolve, reject) => {
90
+ xhr.addEventListener('load', resolve)
91
+ xhr.addEventListener('error', reject)
92
+ })
93
+ // 在发送请求之前cookie为空
94
+ expect(window.document.cookie.length).toBe(0)
95
+ xhr.send('')
96
+ // 等待请求加载完成
97
+ await req
98
+ // 检查是否能读取set-cookie
99
+ expect(window.document.cookie.length).not.toBe(0)
100
+ })
101
+ })
@@ -1,5 +1,5 @@
1
1
  /******************************************************************************
2
- Copyright (c) 2019 wechat-miniprogram.
2
+ Copyright (c) 2019 wechat-miniprogram.
3
3
  Reference and modify code by miniprogram-render/src/bom/cookie.js.
4
4
 
5
5
  Permission to use, copy, modify, and/or distribute this software for any
@@ -63,27 +63,27 @@ function createXMLHttpRequestEvent (event: string, target:XMLHttpRequest, loaded
63
63
  const e = createEvent(event) as XMLHttpRequestEvent
64
64
  try {
65
65
  Object.defineProperties(e, {
66
- 'currentTarget': {
66
+ currentTarget: {
67
67
  enumerable: true,
68
68
  value: target
69
69
  },
70
- 'target': {
70
+ target: {
71
71
  enumerable: true,
72
72
  value: target
73
73
  },
74
- 'loaded': {
74
+ loaded: {
75
75
  enumerable: true,
76
76
  value: loaded || 0
77
77
  },
78
78
  // 读 Content-Range 字段,目前来说作用不大,先和 loaded 保持一致
79
- 'total': {
79
+ total: {
80
80
  enumerable: true,
81
81
  value: loaded || 0
82
82
  }
83
83
  })
84
84
  } catch (err) {
85
85
  // no handler
86
- }
86
+ }
87
87
  return e
88
88
  }
89
89
 
@@ -118,7 +118,10 @@ export class XMLHttpRequest extends Events {
118
118
  #withCredentials: boolean
119
119
  #requestTask: null | Taro.RequestTask<any>
120
120
 
121
- // 事件
121
+ // 事件正常流转: loadstart => progress(可能多次) => load => loadend
122
+ // error 流转: loadstart => error => loadend
123
+ // abort 流转: loadstart => abort => loadend
124
+ // web在线测试: https://developer.mozilla.org/zh-CN/play
122
125
 
123
126
  /** 当 request 被停止时触发,例如当程序调用 XMLHttpRequest.abort() 时 */
124
127
  onabort: ((e: XMLHttpRequestEvent) => void) | null = null
@@ -223,6 +226,7 @@ export class XMLHttpRequest extends Events {
223
226
  // 头信息
224
227
  const header = Object.assign({}, this.#header)
225
228
  // https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
229
+ // @ts-ignore
226
230
  header.cookie = window.document.$$cookie
227
231
  if (!this.withCredentials) {
228
232
  // 不同源,要求 withCredentials 为 true 才携带 cookie
@@ -259,7 +263,7 @@ export class XMLHttpRequest extends Events {
259
263
 
260
264
  if (ENABLE_COOKIE) {
261
265
  // 处理 set-cookie
262
- const setCookieStr = header['Set-Cookie']
266
+ const setCookieStr = this.getResponseHeader('set-cookie')
263
267
 
264
268
  if (setCookieStr && typeof setCookieStr === 'string') {
265
269
  let start = 0
@@ -294,12 +298,13 @@ export class XMLHttpRequest extends Events {
294
298
  // 处理返回数据
295
299
  if (data) {
296
300
  this.#callReadyStateChange(XMLHttpRequest.LOADING)
297
- const loadstartEvent = createXMLHttpRequestEvent('loadstart', this, header['Content-Length'])
301
+ const contentLength = Number(this.getResponseHeader('content-length') || 0)
302
+ const loadstartEvent = createXMLHttpRequestEvent('loadstart', this, contentLength)
298
303
  this.trigger('loadstart', loadstartEvent)
299
304
  isFunction(this.onloadstart) && this.onloadstart(loadstartEvent)
300
305
  this.#response = data
301
306
 
302
- const loadEvent = createXMLHttpRequestEvent('load', this, header['Content-Length'])
307
+ const loadEvent = createXMLHttpRequestEvent('load', this, contentLength)
303
308
  this.trigger('load', loadEvent)
304
309
  isFunction(this.onload) && this.onload(loadEvent)
305
310
  }
@@ -309,8 +314,30 @@ export class XMLHttpRequest extends Events {
309
314
  * 请求失败
310
315
  */
311
316
  #requestFail (err) {
317
+ // 微信小程序,无论接口返回200还是其他,响应无论是否有错误,都会进入 success 回调;只有类似超时这种请求错误才会进入 fail 回调
318
+ //
319
+ /**
320
+ * 阿里系小程序,接口返回非200状态码,会进入 fail 回调, 此时 err 对象结构如下(当错误码为 14 或 19 时,会多返回 status、data、headers。可通过这些字段获取服务端相关错误信息):
321
+ {
322
+ data: "{\"code\": 401,\"msg\":\"登录过期,请重新登录\"}"
323
+ error: 19
324
+ errorMessage: "http status error"
325
+ headers: {date: 'Mon, 14 Aug 2023 08:54:58 GMT', content-type: 'application/json;charset=UTF-8', content-length: '52', connection: 'close', access-control-allow-credentials: 'true', …}
326
+ originalData: "{\"code\": 401,\"msg\":\"登录过期,请重新登录\"}"
327
+ status: 401
328
+ }
329
+ */
330
+ // 统一行为,能正常响应的,都算 success.
331
+ if (err.status) {
332
+ this.#requestSuccess({
333
+ data: err,
334
+ statusCode: err.status,
335
+ header: err.headers
336
+ })
337
+ return
338
+ }
312
339
  this.#status = 0
313
- this.#statusText = err.errMsg
340
+ this.#statusText = err.errMsg || err.errorMessage
314
341
  const errorEvent = createXMLHttpRequestEvent('error', this, 0)
315
342
  this.trigger('error', errorEvent)
316
343
  isFunction(this.onerror) && this.onerror(errorEvent)
@@ -324,7 +351,8 @@ export class XMLHttpRequest extends Events {
324
351
  this.#callReadyStateChange(XMLHttpRequest.DONE)
325
352
 
326
353
  if (this.#status) {
327
- const loadendEvent = createXMLHttpRequestEvent('loadend', this, this.#header['Content-Length'])
354
+ const contentLength = Number(this.getResponseHeader('content-length') || 0)
355
+ const loadendEvent = createXMLHttpRequestEvent('loadend', this, contentLength)
328
356
  this.trigger('loadend', loadendEvent)
329
357
  isFunction(this.onloadend) && this.onloadend(loadendEvent)
330
358
  }
@@ -397,8 +425,7 @@ export class XMLHttpRequest extends Events {
397
425
  }
398
426
 
399
427
  getAllResponseHeaders () {
400
- if (this.#readyState === XMLHttpRequest.UNSENT || this.#readyState === XMLHttpRequest.OPENED || !this.#resHeader)
401
- return ''
428
+ if (this.#readyState === XMLHttpRequest.UNSENT || this.#readyState === XMLHttpRequest.OPENED || !this.#resHeader) { return '' }
402
429
 
403
430
  return Object.keys(this.#resHeader)
404
431
  .map((key) => `${key}: ${this.#resHeader![key]}`)
@@ -406,8 +433,7 @@ export class XMLHttpRequest extends Events {
406
433
  }
407
434
 
408
435
  getResponseHeader (name) {
409
- if (this.#readyState === XMLHttpRequest.UNSENT || this.#readyState === XMLHttpRequest.OPENED || !this.#resHeader)
410
- return null
436
+ if (this.#readyState === XMLHttpRequest.UNSENT || this.#readyState === XMLHttpRequest.OPENED || !this.#resHeader) { return null }
411
437
 
412
438
  // 处理大小写不敏感
413
439
  const key = Object.keys(this.#resHeader).find((item) => item.toLowerCase() === name.toLowerCase())
@@ -1,15 +1,14 @@
1
1
  import { document, window } from '@tarojs/runtime'
2
- import { isWebPlatform } from '@tarojs/shared'
3
2
 
4
3
  import { Cookie, createCookieInstance } from './Cookie'
5
4
  import { type XMLHttpRequestEvent, XMLHttpRequest } from './XMLHttpRequest'
6
5
 
7
6
  declare const ENABLE_COOKIE: boolean
8
7
 
9
- if (!isWebPlatform()) {
8
+ if (process.env.TARO_PLATFORM !== 'web') {
10
9
  if (ENABLE_COOKIE) {
11
10
  const _cookie = createCookieInstance()
12
-
11
+
13
12
  Object.defineProperties(document, {
14
13
  URL: {
15
14
  get () {