@tarojs/plugin-http 3.6.0-beta.2
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 +21 -0
- package/README.MD +59 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +45 -0
- package/dist/runtime.d.ts +94 -0
- package/dist/runtime.js +654 -0
- package/index.js +3 -0
- package/package.json +42 -0
- package/src/__tests__/cookie.spec.js +89 -0
- package/src/__tests__/dom.spec.js +20 -0
- package/src/__tests__/setup.js +1 -0
- package/src/__tests__/utils.js +8 -0
- package/src/index.ts +52 -0
- package/src/runtime/Cookie.ts +312 -0
- package/src/runtime/XMLHttpRequest.ts +398 -0
- package/src/runtime/index.ts +35 -0
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
import { parseUrl, Events, window, document } from '@tarojs/runtime';
|
|
2
|
+
export { document } from '@tarojs/runtime';
|
|
3
|
+
import { setStorage, getStorageSync, request } from '@tarojs/taro';
|
|
4
|
+
import { isString, isFunction } from '@tarojs/shared';
|
|
5
|
+
|
|
6
|
+
/******************************************************************************
|
|
7
|
+
Copyright (c) Microsoft Corporation.
|
|
8
|
+
|
|
9
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
10
|
+
purpose with or without fee is hereby granted.
|
|
11
|
+
|
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
13
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
14
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
15
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
16
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
17
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
18
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
19
|
+
***************************************************************************** */
|
|
20
|
+
|
|
21
|
+
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
22
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
23
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
24
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
28
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
29
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
30
|
+
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");
|
|
31
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var _Cookie_map;
|
|
35
|
+
const STORAGE_KEY = 'PAGE_COOKIE';
|
|
36
|
+
class Cookie {
|
|
37
|
+
constructor() {
|
|
38
|
+
_Cookie_map.set(this, void 0);
|
|
39
|
+
__classPrivateFieldSet(this, _Cookie_map, {}, "f"); // 三维数组,domain - path - key
|
|
40
|
+
}
|
|
41
|
+
static parse(cookieStr) {
|
|
42
|
+
if (!cookieStr && typeof cookieStr !== 'string')
|
|
43
|
+
return null;
|
|
44
|
+
const cookieStrArr = cookieStr.trim().split(';');
|
|
45
|
+
// key-value
|
|
46
|
+
// eslint-disable-next-line no-control-regex
|
|
47
|
+
const parseKeyValue = /^([^=;\x00-\x1F]+)=([^;\n\r\0\x00-\x1F]*).*/.exec(cookieStrArr.shift());
|
|
48
|
+
if (!parseKeyValue)
|
|
49
|
+
return null;
|
|
50
|
+
const key = (parseKeyValue[1] || '').trim();
|
|
51
|
+
const value = (parseKeyValue[2] || '').trim();
|
|
52
|
+
// 其他字段
|
|
53
|
+
let path = null;
|
|
54
|
+
let domain = null;
|
|
55
|
+
let expires = null;
|
|
56
|
+
let maxAge = null;
|
|
57
|
+
let secure = false;
|
|
58
|
+
let httpOnly = false;
|
|
59
|
+
for (let item of cookieStrArr) {
|
|
60
|
+
item = item.trim();
|
|
61
|
+
if (!item)
|
|
62
|
+
continue;
|
|
63
|
+
let [key, value] = item.split('=');
|
|
64
|
+
key = (key || '').trim().toLowerCase();
|
|
65
|
+
value = (value || '').trim();
|
|
66
|
+
if (!key)
|
|
67
|
+
continue;
|
|
68
|
+
switch (key) {
|
|
69
|
+
case 'path':
|
|
70
|
+
if (value[0] === '/')
|
|
71
|
+
path = value;
|
|
72
|
+
break;
|
|
73
|
+
case 'domain':
|
|
74
|
+
value = value.replace(/^\./, '').toLowerCase();
|
|
75
|
+
if (value)
|
|
76
|
+
domain = value;
|
|
77
|
+
break;
|
|
78
|
+
case 'expires':
|
|
79
|
+
if (value) {
|
|
80
|
+
const timeStamp = Date.parse(value);
|
|
81
|
+
if (timeStamp)
|
|
82
|
+
expires = timeStamp;
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
case 'max-age':
|
|
86
|
+
if (/^-?[0-9]+$/.test(value))
|
|
87
|
+
maxAge = +value * 1000;
|
|
88
|
+
break;
|
|
89
|
+
case 'secure':
|
|
90
|
+
secure = true;
|
|
91
|
+
break;
|
|
92
|
+
case 'httponly':
|
|
93
|
+
httpOnly = true;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
key,
|
|
99
|
+
value,
|
|
100
|
+
path,
|
|
101
|
+
domain,
|
|
102
|
+
expires,
|
|
103
|
+
maxAge,
|
|
104
|
+
secure,
|
|
105
|
+
httpOnly,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 判断 domain
|
|
110
|
+
*/
|
|
111
|
+
$_checkDomain(host, cookieDomain) {
|
|
112
|
+
if (host === cookieDomain)
|
|
113
|
+
return true;
|
|
114
|
+
const index = host.indexOf(`.${cookieDomain}`);
|
|
115
|
+
return index > 0 && cookieDomain.length + index + 1 === host.length;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 判断 path
|
|
119
|
+
*/
|
|
120
|
+
$_checkPath(path, cookiePath) {
|
|
121
|
+
if (path === cookiePath)
|
|
122
|
+
return true;
|
|
123
|
+
cookiePath = cookiePath === '/' ? '' : cookiePath;
|
|
124
|
+
return path.indexOf(`${cookiePath}/`) === 0;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 判断过期
|
|
128
|
+
*/
|
|
129
|
+
$_checkExpires(cookie) {
|
|
130
|
+
const now = Date.now();
|
|
131
|
+
// maxAge 优先
|
|
132
|
+
if (cookie.maxAge !== null)
|
|
133
|
+
return cookie.createTime + cookie.maxAge > now;
|
|
134
|
+
// 判断 expires
|
|
135
|
+
if (cookie.expires !== null)
|
|
136
|
+
return cookie.expires > now;
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 设置 cookie
|
|
141
|
+
*/
|
|
142
|
+
setCookie(cookie, url) {
|
|
143
|
+
cookie = Cookie.parse(cookie);
|
|
144
|
+
if (!cookie)
|
|
145
|
+
return;
|
|
146
|
+
const { hostname, port, pathname } = parseUrl(url);
|
|
147
|
+
const host = (hostname || '') + (port ? ':' + port : '') || '';
|
|
148
|
+
const path = (pathname || '')[0] === '/' ? pathname : '/';
|
|
149
|
+
if (cookie.domain) {
|
|
150
|
+
// 判断 domain
|
|
151
|
+
if (!this.$_checkDomain(host, cookie.domain))
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// 使用 host 作为默认的 domain
|
|
156
|
+
cookie.domain = host;
|
|
157
|
+
}
|
|
158
|
+
// 需要设置 path 字段的情况,取 url 中除去最后一节的 path
|
|
159
|
+
if (!cookie.path || cookie.path[0] !== '/') {
|
|
160
|
+
const lastIndex = path.lastIndexOf('/');
|
|
161
|
+
cookie.path = lastIndex === 0 ? path : path.substr(0, lastIndex);
|
|
162
|
+
}
|
|
163
|
+
// 存入 cookie
|
|
164
|
+
const map = __classPrivateFieldGet(this, _Cookie_map, "f");
|
|
165
|
+
const cookieDomain = cookie.domain;
|
|
166
|
+
const cookiePath = cookie.path;
|
|
167
|
+
const cookieKey = cookie.key;
|
|
168
|
+
if (!map[cookieDomain])
|
|
169
|
+
map[cookieDomain] = {};
|
|
170
|
+
if (!map[cookieDomain][cookiePath])
|
|
171
|
+
map[cookieDomain][cookiePath] = {};
|
|
172
|
+
const oldCookie = map[cookieDomain][cookiePath][cookieKey];
|
|
173
|
+
cookie.createTime = (oldCookie && oldCookie.createTime) || Date.now();
|
|
174
|
+
if (this.$_checkExpires(cookie)) {
|
|
175
|
+
// 未过期
|
|
176
|
+
map[cookieDomain][cookiePath][cookieKey] = cookie;
|
|
177
|
+
}
|
|
178
|
+
else if (oldCookie) {
|
|
179
|
+
// 存在旧 cookie,且被设置为已过期
|
|
180
|
+
delete map[cookieDomain][cookiePath][cookieKey];
|
|
181
|
+
}
|
|
182
|
+
// 持久化 cookie
|
|
183
|
+
setStorage &&
|
|
184
|
+
setStorage({
|
|
185
|
+
key: STORAGE_KEY,
|
|
186
|
+
data: this.serialize(),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* 拉取 cookie
|
|
191
|
+
*/
|
|
192
|
+
getCookie(url, includeHttpOnly = false) {
|
|
193
|
+
const { protocol, hostname, port, pathname } = parseUrl(url);
|
|
194
|
+
const host = (hostname || '') + (port ? ':' + port : '') || '';
|
|
195
|
+
const path = (pathname || '')[0] === '/' ? pathname : '/';
|
|
196
|
+
const res = [];
|
|
197
|
+
const map = __classPrivateFieldGet(this, _Cookie_map, "f");
|
|
198
|
+
const domainList = Object.keys(map);
|
|
199
|
+
for (const domainItem of domainList) {
|
|
200
|
+
// 判断 domain
|
|
201
|
+
if (this.$_checkDomain(host, domainItem)) {
|
|
202
|
+
const domainMap = map[domainItem] || {};
|
|
203
|
+
const pathList = Object.keys(domainMap);
|
|
204
|
+
for (const pathItem of pathList) {
|
|
205
|
+
// 判断 path
|
|
206
|
+
if (this.$_checkPath(path, pathItem)) {
|
|
207
|
+
const pathMap = map[domainItem][pathItem] || {};
|
|
208
|
+
Object.keys(pathMap).forEach((key) => {
|
|
209
|
+
const cookie = pathMap[key];
|
|
210
|
+
if (!cookie)
|
|
211
|
+
return;
|
|
212
|
+
// 判断协议
|
|
213
|
+
if (cookie.secure && protocol !== 'https:' && protocol !== 'wss:')
|
|
214
|
+
return;
|
|
215
|
+
if (!includeHttpOnly && cookie.httpOnly && protocol && protocol !== 'http:')
|
|
216
|
+
return;
|
|
217
|
+
// 判断过期
|
|
218
|
+
if (this.$_checkExpires(cookie)) {
|
|
219
|
+
res.push(cookie);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// 过期,删掉
|
|
223
|
+
delete map[domainItem][pathItem][key];
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return res
|
|
231
|
+
.sort((a, b) => {
|
|
232
|
+
const gap = a.createTime - b.createTime;
|
|
233
|
+
if (!gap) {
|
|
234
|
+
return a.key < b.key ? -1 : 1;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
return gap;
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
.map((cookie) => `${cookie.key}=${cookie.value}`)
|
|
241
|
+
.join('; ');
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* 序列化
|
|
245
|
+
*/
|
|
246
|
+
serialize() {
|
|
247
|
+
try {
|
|
248
|
+
return JSON.stringify(__classPrivateFieldGet(this, _Cookie_map, "f"));
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
// eslint-disable-next-line no-console
|
|
252
|
+
console.log('cannot serialize the cookie');
|
|
253
|
+
return '';
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 反序列化
|
|
258
|
+
*/
|
|
259
|
+
deserialize(str) {
|
|
260
|
+
let map = {};
|
|
261
|
+
try {
|
|
262
|
+
map = JSON.parse(str);
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
// eslint-disable-next-line no-console
|
|
266
|
+
console.log('cannot deserialize the cookie');
|
|
267
|
+
map = {};
|
|
268
|
+
}
|
|
269
|
+
// 合并 cookie
|
|
270
|
+
const domainList = Object.keys(map);
|
|
271
|
+
for (const domainItem of domainList) {
|
|
272
|
+
const domainMap = map[domainItem] || {};
|
|
273
|
+
const pathList = Object.keys(domainMap);
|
|
274
|
+
for (const pathItem of pathList) {
|
|
275
|
+
const pathMap = map[domainItem][pathItem] || {};
|
|
276
|
+
Object.keys(pathMap).forEach((key) => {
|
|
277
|
+
const cookie = pathMap[key];
|
|
278
|
+
if (!cookie)
|
|
279
|
+
return;
|
|
280
|
+
// 已存在则不覆盖
|
|
281
|
+
if (!__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem])
|
|
282
|
+
__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem] = {};
|
|
283
|
+
if (!__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem])
|
|
284
|
+
__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem] = {};
|
|
285
|
+
if (!__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem][key])
|
|
286
|
+
__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem][key] = cookie;
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
_Cookie_map = new WeakMap();
|
|
293
|
+
/**
|
|
294
|
+
* 创建 cookie 实例并反序列化
|
|
295
|
+
* @returns
|
|
296
|
+
*/
|
|
297
|
+
function createCookieInstance() {
|
|
298
|
+
const cookieInstance = new Cookie();
|
|
299
|
+
try {
|
|
300
|
+
const cookie = getStorageSync(STORAGE_KEY);
|
|
301
|
+
if (cookie)
|
|
302
|
+
cookieInstance.deserialize(cookie);
|
|
303
|
+
}
|
|
304
|
+
catch (err) {
|
|
305
|
+
// ignore
|
|
306
|
+
}
|
|
307
|
+
return cookieInstance;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
var _XMLHttpRequest_instances, _XMLHttpRequest_method, _XMLHttpRequest_url, _XMLHttpRequest_data, _XMLHttpRequest_status, _XMLHttpRequest_statusText, _XMLHttpRequest_readyState, _XMLHttpRequest_header, _XMLHttpRequest_responseType, _XMLHttpRequest_resHeader, _XMLHttpRequest_response, _XMLHttpRequest_timeout, _XMLHttpRequest_withCredentials, _XMLHttpRequest_requestTask, _XMLHttpRequest_callReadyStateChange, _XMLHttpRequest_callRequest, _XMLHttpRequest_requestSuccess, _XMLHttpRequest_requestFail, _XMLHttpRequest_requestComplete;
|
|
311
|
+
const SUPPORT_METHOD = ['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'];
|
|
312
|
+
const STATUS_TEXT_MAP = {
|
|
313
|
+
100: 'Continue',
|
|
314
|
+
101: 'Switching protocols',
|
|
315
|
+
200: 'OK',
|
|
316
|
+
201: 'Created',
|
|
317
|
+
202: 'Accepted',
|
|
318
|
+
203: 'Non-Authoritative Information',
|
|
319
|
+
204: 'No Content',
|
|
320
|
+
205: 'Reset Content',
|
|
321
|
+
206: 'Partial Content',
|
|
322
|
+
300: 'Multiple Choices',
|
|
323
|
+
301: 'Moved Permanently',
|
|
324
|
+
302: 'Found',
|
|
325
|
+
303: 'See Other',
|
|
326
|
+
304: 'Not Modified',
|
|
327
|
+
305: 'Use Proxy',
|
|
328
|
+
307: 'Temporary Redirect',
|
|
329
|
+
400: 'Bad Request',
|
|
330
|
+
401: 'Unauthorized',
|
|
331
|
+
402: 'Payment Required',
|
|
332
|
+
403: 'Forbidden',
|
|
333
|
+
404: 'Not Found',
|
|
334
|
+
405: 'Method Not Allowed',
|
|
335
|
+
406: 'Not Acceptable',
|
|
336
|
+
407: 'Proxy Authentication Required',
|
|
337
|
+
408: 'Request Timeout',
|
|
338
|
+
409: 'Conflict',
|
|
339
|
+
410: 'Gone',
|
|
340
|
+
411: 'Length Required',
|
|
341
|
+
412: 'Precondition Failed',
|
|
342
|
+
413: 'Request Entity Too Large',
|
|
343
|
+
414: 'Request-URI Too Long',
|
|
344
|
+
415: 'Unsupported Media Type',
|
|
345
|
+
416: 'Requested Range Not Suitable',
|
|
346
|
+
417: 'Expectation Failed',
|
|
347
|
+
500: 'Internal Server Error',
|
|
348
|
+
501: 'Not Implemented',
|
|
349
|
+
502: 'Bad Gateway',
|
|
350
|
+
503: 'Service Unavailable',
|
|
351
|
+
504: 'Gateway Timeout',
|
|
352
|
+
505: 'HTTP Version Not Supported',
|
|
353
|
+
};
|
|
354
|
+
// https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
|
|
355
|
+
class XMLHttpRequest extends Events {
|
|
356
|
+
constructor() {
|
|
357
|
+
super();
|
|
358
|
+
_XMLHttpRequest_instances.add(this);
|
|
359
|
+
_XMLHttpRequest_method.set(this, void 0);
|
|
360
|
+
_XMLHttpRequest_url.set(this, void 0);
|
|
361
|
+
_XMLHttpRequest_data.set(this, void 0);
|
|
362
|
+
_XMLHttpRequest_status.set(this, void 0);
|
|
363
|
+
_XMLHttpRequest_statusText.set(this, void 0);
|
|
364
|
+
_XMLHttpRequest_readyState.set(this, void 0);
|
|
365
|
+
_XMLHttpRequest_header.set(this, void 0);
|
|
366
|
+
_XMLHttpRequest_responseType.set(this, void 0);
|
|
367
|
+
_XMLHttpRequest_resHeader.set(this, void 0);
|
|
368
|
+
_XMLHttpRequest_response.set(this, void 0);
|
|
369
|
+
_XMLHttpRequest_timeout.set(this, void 0);
|
|
370
|
+
_XMLHttpRequest_withCredentials.set(this, void 0);
|
|
371
|
+
_XMLHttpRequest_requestTask.set(this, void 0);
|
|
372
|
+
// 事件
|
|
373
|
+
/** 当 request 被停止时触发,例如当程序调用 XMLHttpRequest.abort() 时 */
|
|
374
|
+
this.onabort = null;
|
|
375
|
+
/** 当 request 遭遇错误时触发 */
|
|
376
|
+
this.onerror = null;
|
|
377
|
+
/** 接收到响应数据时触发 */
|
|
378
|
+
this.onloadstart = null;
|
|
379
|
+
/** 请求成功完成时触发 */
|
|
380
|
+
this.onload = null;
|
|
381
|
+
/** 当请求结束时触发,无论请求成功 ( load) 还是失败 (abort 或 error)。 */
|
|
382
|
+
this.onloadend = null;
|
|
383
|
+
/** 在预设时间内没有接收到响应时触发 */
|
|
384
|
+
this.ontimeout = null;
|
|
385
|
+
/** 当 readyState 属性发生变化时,调用的事件处理器 */
|
|
386
|
+
this.onreadystatechange = null;
|
|
387
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_method, '', "f");
|
|
388
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_url, '', "f");
|
|
389
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_data, null, "f");
|
|
390
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_status, 0, "f");
|
|
391
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_statusText, '', "f");
|
|
392
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_readyState, XMLHttpRequest.UNSENT, "f");
|
|
393
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_header, {
|
|
394
|
+
Accept: '*/*',
|
|
395
|
+
}, "f");
|
|
396
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_responseType, '', "f");
|
|
397
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_resHeader, null, "f");
|
|
398
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_response, null, "f");
|
|
399
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_timeout, 0, "f");
|
|
400
|
+
/** 向前兼容,默认为 true */
|
|
401
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_withCredentials, true, "f");
|
|
402
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_requestTask, null, "f");
|
|
403
|
+
}
|
|
404
|
+
// 欺骗一些库让其认为是原生的xhr
|
|
405
|
+
static toString() {
|
|
406
|
+
return 'function XMLHttpRequest() { [native code] }';
|
|
407
|
+
}
|
|
408
|
+
toString() {
|
|
409
|
+
return '[object XMLHttpRequest]';
|
|
410
|
+
}
|
|
411
|
+
addEventListener(event, callback) {
|
|
412
|
+
if (!isString(event))
|
|
413
|
+
return;
|
|
414
|
+
this.on(event, callback, null);
|
|
415
|
+
}
|
|
416
|
+
removeEventListener(event, callback) {
|
|
417
|
+
if (!isString(event))
|
|
418
|
+
return;
|
|
419
|
+
this.off(event, callback, null);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* 对外属性和方法
|
|
423
|
+
*/
|
|
424
|
+
get timeout() {
|
|
425
|
+
return __classPrivateFieldGet(this, _XMLHttpRequest_timeout, "f");
|
|
426
|
+
}
|
|
427
|
+
set timeout(timeout) {
|
|
428
|
+
if (typeof timeout !== 'number' || !isFinite(timeout) || timeout <= 0)
|
|
429
|
+
return;
|
|
430
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_timeout, timeout, "f");
|
|
431
|
+
}
|
|
432
|
+
get status() {
|
|
433
|
+
return __classPrivateFieldGet(this, _XMLHttpRequest_status, "f");
|
|
434
|
+
}
|
|
435
|
+
get statusText() {
|
|
436
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.OPENED)
|
|
437
|
+
return '';
|
|
438
|
+
return STATUS_TEXT_MAP[__classPrivateFieldGet(this, _XMLHttpRequest_status, "f") + ''] || __classPrivateFieldGet(this, _XMLHttpRequest_statusText, "f") || '';
|
|
439
|
+
}
|
|
440
|
+
get readyState() {
|
|
441
|
+
return __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f");
|
|
442
|
+
}
|
|
443
|
+
get responseType() {
|
|
444
|
+
return __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f");
|
|
445
|
+
}
|
|
446
|
+
set responseType(value) {
|
|
447
|
+
if (typeof value !== 'string')
|
|
448
|
+
return;
|
|
449
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_responseType, value, "f");
|
|
450
|
+
}
|
|
451
|
+
get responseText() {
|
|
452
|
+
if (!__classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") || __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") === 'text') {
|
|
453
|
+
return __classPrivateFieldGet(this, _XMLHttpRequest_response, "f");
|
|
454
|
+
}
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
get response() {
|
|
458
|
+
return __classPrivateFieldGet(this, _XMLHttpRequest_response, "f");
|
|
459
|
+
}
|
|
460
|
+
get withCredentials() {
|
|
461
|
+
return __classPrivateFieldGet(this, _XMLHttpRequest_withCredentials, "f");
|
|
462
|
+
}
|
|
463
|
+
set withCredentials(value) {
|
|
464
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_withCredentials, !!value, "f");
|
|
465
|
+
}
|
|
466
|
+
abort() {
|
|
467
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f")) {
|
|
468
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f").abort();
|
|
469
|
+
this.trigger('abort');
|
|
470
|
+
isFunction(this.onabort) && this.onabort();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
getAllResponseHeaders() {
|
|
474
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f"))
|
|
475
|
+
return '';
|
|
476
|
+
return Object.keys(__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f"))
|
|
477
|
+
.map((key) => `${key}: ${__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")[key]}`)
|
|
478
|
+
.join('\r\n');
|
|
479
|
+
}
|
|
480
|
+
getResponseHeader(name) {
|
|
481
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === XMLHttpRequest.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f"))
|
|
482
|
+
return null;
|
|
483
|
+
// 处理大小写不敏感
|
|
484
|
+
const key = Object.keys(__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")).find((item) => item.toLowerCase() === name.toLowerCase());
|
|
485
|
+
const value = key ? __classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")[key] : null;
|
|
486
|
+
return typeof value === 'string' ? value : null;
|
|
487
|
+
}
|
|
488
|
+
open(method, url) {
|
|
489
|
+
if (typeof method === 'string')
|
|
490
|
+
method = method.toUpperCase();
|
|
491
|
+
if (SUPPORT_METHOD.indexOf(method) < 0)
|
|
492
|
+
return;
|
|
493
|
+
if (!url || typeof url !== 'string')
|
|
494
|
+
return;
|
|
495
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_method, method, "f");
|
|
496
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_url, url, "f");
|
|
497
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.OPENED);
|
|
498
|
+
}
|
|
499
|
+
setRequestHeader(header, value) {
|
|
500
|
+
if (typeof header === 'string' && typeof value === 'string') {
|
|
501
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_header, "f")[header] = value;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
send(data) {
|
|
505
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") !== XMLHttpRequest.OPENED)
|
|
506
|
+
return;
|
|
507
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_data, data, "f");
|
|
508
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callRequest).call(this);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
_XMLHttpRequest_method = new WeakMap(), _XMLHttpRequest_url = new WeakMap(), _XMLHttpRequest_data = new WeakMap(), _XMLHttpRequest_status = new WeakMap(), _XMLHttpRequest_statusText = new WeakMap(), _XMLHttpRequest_readyState = new WeakMap(), _XMLHttpRequest_header = new WeakMap(), _XMLHttpRequest_responseType = new WeakMap(), _XMLHttpRequest_resHeader = new WeakMap(), _XMLHttpRequest_response = new WeakMap(), _XMLHttpRequest_timeout = new WeakMap(), _XMLHttpRequest_withCredentials = new WeakMap(), _XMLHttpRequest_requestTask = new WeakMap(), _XMLHttpRequest_instances = new WeakSet(), _XMLHttpRequest_callReadyStateChange = function _XMLHttpRequest_callReadyStateChange(readyState) {
|
|
512
|
+
const hasChange = readyState !== __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f");
|
|
513
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_readyState, readyState, "f");
|
|
514
|
+
if (hasChange) {
|
|
515
|
+
this.trigger('readystatechange');
|
|
516
|
+
isFunction(this.onreadystatechange) && this.onreadystatechange();
|
|
517
|
+
}
|
|
518
|
+
}, _XMLHttpRequest_callRequest = function _XMLHttpRequest_callRequest() {
|
|
519
|
+
if (!window || !window.document) {
|
|
520
|
+
console.warn('this page has been unloaded, so this request will be canceled.');
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_timeout, "f")) {
|
|
524
|
+
setTimeout(() => {
|
|
525
|
+
if (!__classPrivateFieldGet(this, _XMLHttpRequest_status, "f") && __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") !== XMLHttpRequest.DONE) {
|
|
526
|
+
// 超时
|
|
527
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f"))
|
|
528
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f").abort();
|
|
529
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.DONE);
|
|
530
|
+
this.trigger('timeout');
|
|
531
|
+
isFunction(this.ontimeout) && this.ontimeout();
|
|
532
|
+
}
|
|
533
|
+
}, __classPrivateFieldGet(this, _XMLHttpRequest_timeout, "f"));
|
|
534
|
+
}
|
|
535
|
+
// 重置各种状态
|
|
536
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_status, 0, "f");
|
|
537
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_statusText, '', "f");
|
|
538
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_readyState, XMLHttpRequest.OPENED, "f");
|
|
539
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_resHeader, null, "f");
|
|
540
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_response, null, "f");
|
|
541
|
+
// 补完 url
|
|
542
|
+
let url = __classPrivateFieldGet(this, _XMLHttpRequest_url, "f");
|
|
543
|
+
url = url.indexOf('//') === -1 ? window.location.origin + url : url;
|
|
544
|
+
// 头信息
|
|
545
|
+
const header = Object.assign({}, __classPrivateFieldGet(this, _XMLHttpRequest_header, "f"));
|
|
546
|
+
header.cookie = window.document.cookie;
|
|
547
|
+
if (!this.withCredentials) {
|
|
548
|
+
// 不同源,要求 withCredentials 为 true 才携带 cookie
|
|
549
|
+
const { origin } = parseUrl(url);
|
|
550
|
+
if (origin !== window.location.origin)
|
|
551
|
+
delete header.cookie;
|
|
552
|
+
}
|
|
553
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_requestTask, request({
|
|
554
|
+
url,
|
|
555
|
+
data: __classPrivateFieldGet(this, _XMLHttpRequest_data, "f") || {},
|
|
556
|
+
header,
|
|
557
|
+
// @ts-ignore
|
|
558
|
+
method: __classPrivateFieldGet(this, _XMLHttpRequest_method, "f"),
|
|
559
|
+
dataType: __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") === 'json' ? 'json' : 'text',
|
|
560
|
+
responseType: __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") === 'arraybuffer' ? 'arraybuffer' : 'text',
|
|
561
|
+
success: __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestSuccess).bind(this),
|
|
562
|
+
fail: __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestFail).bind(this),
|
|
563
|
+
complete: __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestComplete).bind(this),
|
|
564
|
+
}), "f");
|
|
565
|
+
}, _XMLHttpRequest_requestSuccess = function _XMLHttpRequest_requestSuccess({ data, statusCode, header }) {
|
|
566
|
+
if (!window || !window.document) {
|
|
567
|
+
console.warn('this page has been unloaded, so this request will be canceled.');
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_status, statusCode, "f");
|
|
571
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_resHeader, header, "f");
|
|
572
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.HEADERS_RECEIVED);
|
|
573
|
+
if (ENABLE_COOKIE) {
|
|
574
|
+
// 处理 set-cookie
|
|
575
|
+
const setCookieStr = header['Set-Cookie'];
|
|
576
|
+
if (setCookieStr && typeof setCookieStr === 'string') {
|
|
577
|
+
let start = 0;
|
|
578
|
+
let startSplit = 0;
|
|
579
|
+
let nextSplit = setCookieStr.indexOf(',', startSplit);
|
|
580
|
+
const cookies = [];
|
|
581
|
+
while (nextSplit >= 0) {
|
|
582
|
+
const lastSplitStr = setCookieStr.substring(start, nextSplit);
|
|
583
|
+
const splitStr = setCookieStr.substr(nextSplit);
|
|
584
|
+
// eslint-disable-next-line no-control-regex
|
|
585
|
+
if (/^,\s*([^,=;\x00-\x1F]+)=([^;\n\r\0\x00-\x1F]*).*/.test(splitStr)) {
|
|
586
|
+
// 分割成功,则上一片是完整 cookie
|
|
587
|
+
cookies.push(lastSplitStr);
|
|
588
|
+
start = nextSplit + 1;
|
|
589
|
+
}
|
|
590
|
+
startSplit = nextSplit + 1;
|
|
591
|
+
nextSplit = setCookieStr.indexOf(',', startSplit);
|
|
592
|
+
}
|
|
593
|
+
// 塞入最后一片 cookie
|
|
594
|
+
cookies.push(setCookieStr.substr(start));
|
|
595
|
+
cookies.forEach((cookie) => {
|
|
596
|
+
window.document.cookie = cookie;
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
// 处理返回数据
|
|
601
|
+
if (data) {
|
|
602
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.LOADING);
|
|
603
|
+
this.trigger('loadstart');
|
|
604
|
+
isFunction(this.onloadstart) && this.onloadstart();
|
|
605
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_response, data, "f");
|
|
606
|
+
this.trigger('load');
|
|
607
|
+
isFunction(this.onload) && this.onload();
|
|
608
|
+
}
|
|
609
|
+
}, _XMLHttpRequest_requestFail = function _XMLHttpRequest_requestFail(err) {
|
|
610
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_status, 0, "f");
|
|
611
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_statusText, err.errMsg, "f");
|
|
612
|
+
this.trigger('error');
|
|
613
|
+
isFunction(this.onerror) && this.onerror(err);
|
|
614
|
+
}, _XMLHttpRequest_requestComplete = function _XMLHttpRequest_requestComplete() {
|
|
615
|
+
__classPrivateFieldSet(this, _XMLHttpRequest_requestTask, null, "f");
|
|
616
|
+
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, XMLHttpRequest.DONE);
|
|
617
|
+
if (__classPrivateFieldGet(this, _XMLHttpRequest_status, "f")) {
|
|
618
|
+
this.trigger('loadend');
|
|
619
|
+
isFunction(this.onloadend) && this.onloadend();
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
XMLHttpRequest.UNSENT = 0;
|
|
623
|
+
XMLHttpRequest.OPENED = 1;
|
|
624
|
+
XMLHttpRequest.HEADERS_RECEIVED = 2;
|
|
625
|
+
XMLHttpRequest.LOADING = 3;
|
|
626
|
+
XMLHttpRequest.DONE = 4;
|
|
627
|
+
|
|
628
|
+
if (process.env.TARO_ENV !== 'h5') {
|
|
629
|
+
if (ENABLE_COOKIE) {
|
|
630
|
+
const _cookie = createCookieInstance();
|
|
631
|
+
Object.defineProperties(document, {
|
|
632
|
+
URL: {
|
|
633
|
+
get() {
|
|
634
|
+
if (this.defaultView)
|
|
635
|
+
return this.defaultView.location.href;
|
|
636
|
+
return '';
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
cookie: {
|
|
640
|
+
get() {
|
|
641
|
+
return _cookie.getCookie(this.URL);
|
|
642
|
+
},
|
|
643
|
+
set(value) {
|
|
644
|
+
if (!value || typeof value !== 'string')
|
|
645
|
+
return;
|
|
646
|
+
_cookie.setCookie(value, this.URL);
|
|
647
|
+
},
|
|
648
|
+
},
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
window.XMLHttpRequest = XMLHttpRequest;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
export { Cookie, XMLHttpRequest };
|
package/index.js
ADDED