@tarojs/plugin-http
Version:
Taro 小程序端支持使用 web 请求 的插件
735 lines (723 loc) • 32.5 kB
JavaScript
import { parseUrl, Events, createEvent, window, document } from '@tarojs/runtime';
export { document } from '@tarojs/runtime';
import { getStorageSync, setStorage, request } from '@tarojs/taro';
import { isString, isFunction } from '@tarojs/shared';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}
function __classPrivateFieldSet(receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
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");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
var _Cookie_map;
const STORAGE_KEY = 'PAGE_COOKIE';
class Cookie {
constructor() {
_Cookie_map.set(this, void 0);
__classPrivateFieldSet(this, _Cookie_map, {}, "f"); // 三维数组,domain - path - key
}
static parse(cookieStr) {
if (!cookieStr && typeof cookieStr !== 'string')
return null;
const cookieStrArr = cookieStr.trim().split(';');
// key-value
// eslint-disable-next-line no-control-regex
const parseKeyValue = /^([^=;\x00-\x1F]+)=([^;\n\r\0\x00-\x1F]*).*/.exec(cookieStrArr.shift());
if (!parseKeyValue)
return null;
const key = (parseKeyValue[1] || '').trim();
const value = (parseKeyValue[2] || '').trim();
// 其他字段
let path = null;
let domain = null;
let expires = null;
let maxAge = null;
let secure = false;
let httpOnly = false;
for (let item of cookieStrArr) {
item = item.trim();
if (!item)
continue;
let [key, value] = item.split('=');
key = (key || '').trim().toLowerCase();
value = (value || '').trim();
if (!key)
continue;
switch (key) {
case 'path':
if (value[0] === '/')
path = value;
break;
case 'domain':
value = value.replace(/^\./, '').toLowerCase();
if (value)
domain = value;
break;
case 'expires':
if (value) {
const timeStamp = Date.parse(value);
if (timeStamp)
expires = timeStamp;
}
break;
case 'max-age':
if (/^-?[0-9]+$/.test(value))
maxAge = +value * 1000;
break;
case 'secure':
secure = true;
break;
case 'httponly':
httpOnly = true;
break;
}
}
return {
key,
value,
path,
domain,
expires,
maxAge,
secure,
httpOnly,
};
}
/**
* 判断 domain
*/
$_checkDomain(host, cookieDomain) {
if (host === cookieDomain)
return true;
const index = host.indexOf(`.${cookieDomain}`);
return index > 0 && cookieDomain.length + index + 1 === host.length;
}
/**
* 判断 path
*/
$_checkPath(path, cookiePath) {
if (path === cookiePath)
return true;
cookiePath = cookiePath === '/' ? '' : cookiePath;
return path.indexOf(`${cookiePath}/`) === 0;
}
/**
* 判断过期
*/
$_checkExpires(cookie) {
const now = Date.now();
// maxAge 优先
if (cookie.maxAge !== null)
return cookie.createTime + cookie.maxAge > now;
// 判断 expires
if (cookie.expires !== null)
return cookie.expires > now;
return true;
}
/**
* 设置 cookie
*/
setCookie(cookie, url) {
cookie = Cookie.parse(cookie);
if (!cookie)
return;
const { hostname, port, pathname } = parseUrl(url);
const host = (hostname || '') + (port ? ':' + port : '') || '';
const path = (pathname || '')[0] === '/' ? pathname : '/';
if (cookie.domain) {
// 判断 domain
if (!this.$_checkDomain(host, cookie.domain))
return;
}
else {
// 使用 host 作为默认的 domain
cookie.domain = host;
}
// 需要设置 path 字段的情况,取 url 中除去最后一节的 path
if (!cookie.path || cookie.path[0] !== '/') {
const lastIndex = path.lastIndexOf('/');
cookie.path = lastIndex === 0 ? path : path.substr(0, lastIndex);
}
// 存入 cookie
const map = __classPrivateFieldGet(this, _Cookie_map, "f");
const cookieDomain = cookie.domain;
const cookiePath = cookie.path;
const cookieKey = cookie.key;
if (!map[cookieDomain])
map[cookieDomain] = {};
if (!map[cookieDomain][cookiePath])
map[cookieDomain][cookiePath] = {};
const oldCookie = map[cookieDomain][cookiePath][cookieKey];
cookie.createTime = (oldCookie && oldCookie.createTime) || Date.now();
if (this.$_checkExpires(cookie)) {
// 未过期
map[cookieDomain][cookiePath][cookieKey] = cookie;
}
else if (oldCookie) {
// 存在旧 cookie,且被设置为已过期
delete map[cookieDomain][cookiePath][cookieKey];
}
// 持久化 cookie
setStorage &&
setStorage({
key: STORAGE_KEY,
data: this.serialize(),
});
}
/**
* 拉取 cookie
*/
getCookie(url, includeHttpOnly = false) {
const { protocol, hostname, port, pathname } = parseUrl(url);
const host = (hostname || '') + (port ? ':' + port : '') || '';
const path = (pathname || '')[0] === '/' ? pathname : '/';
const res = [];
const map = __classPrivateFieldGet(this, _Cookie_map, "f");
const domainList = Object.keys(map);
for (const domainItem of domainList) {
// 判断 domain
if (this.$_checkDomain(host, domainItem)) {
const domainMap = map[domainItem] || {};
const pathList = Object.keys(domainMap);
for (const pathItem of pathList) {
// 判断 path
if (this.$_checkPath(path, pathItem)) {
const pathMap = map[domainItem][pathItem] || {};
Object.keys(pathMap).forEach((key) => {
const cookie = pathMap[key];
if (!cookie)
return;
// 判断协议
if (cookie.secure && protocol !== 'https:' && protocol !== 'wss:')
return;
if (!includeHttpOnly && cookie.httpOnly && protocol && protocol !== 'http:')
return;
// 判断过期
if (this.$_checkExpires(cookie)) {
res.push(cookie);
}
else {
// 过期,删掉
delete map[domainItem][pathItem][key];
}
});
}
}
}
}
return res
.sort((a, b) => {
const gap = a.createTime - b.createTime;
if (!gap) {
return a.key < b.key ? -1 : 1;
}
else {
return gap;
}
})
.map((cookie) => `${cookie.key}=${cookie.value}`)
.join('; ');
}
/**
* 序列化
*/
serialize() {
try {
return JSON.stringify(__classPrivateFieldGet(this, _Cookie_map, "f"));
}
catch (err) {
// eslint-disable-next-line no-console
console.log('cannot serialize the cookie');
return '';
}
}
/**
* 反序列化
*/
deserialize(str) {
let map = {};
try {
map = JSON.parse(str);
}
catch (err) {
// eslint-disable-next-line no-console
console.log('cannot deserialize the cookie');
map = {};
}
// 合并 cookie
const domainList = Object.keys(map);
for (const domainItem of domainList) {
const domainMap = map[domainItem] || {};
const pathList = Object.keys(domainMap);
for (const pathItem of pathList) {
const pathMap = map[domainItem][pathItem] || {};
Object.keys(pathMap).forEach((key) => {
const cookie = pathMap[key];
if (!cookie)
return;
// 已存在则不覆盖
if (!__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem])
__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem] = {};
if (!__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem])
__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem] = {};
if (!__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem][key])
__classPrivateFieldGet(this, _Cookie_map, "f")[domainItem][pathItem][key] = cookie;
});
}
}
}
}
_Cookie_map = new WeakMap();
/**
* 创建 cookie 实例并反序列化
* @returns
*/
function createCookieInstance() {
const cookieInstance = new Cookie();
try {
const cookie = getStorageSync(STORAGE_KEY);
if (cookie)
cookieInstance.deserialize(cookie);
}
catch (err) {
// ignore
}
return cookieInstance;
}
var _XMLHttpRequest_instances, _a, _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;
const SUPPORT_METHOD = ['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'];
const STATUS_TEXT_MAP = {
100: 'Continue',
101: 'Switching protocols',
200: 'OK',
201: 'Created',
202: 'Accepted',
203: 'Non-Authoritative Information',
204: 'No Content',
205: 'Reset Content',
206: 'Partial Content',
300: 'Multiple Choices',
301: 'Moved Permanently',
302: 'Found',
303: 'See Other',
304: 'Not Modified',
305: 'Use Proxy',
307: 'Temporary Redirect',
400: 'Bad Request',
401: 'Unauthorized',
402: 'Payment Required',
403: 'Forbidden',
404: 'Not Found',
405: 'Method Not Allowed',
406: 'Not Acceptable',
407: 'Proxy Authentication Required',
408: 'Request Timeout',
409: 'Conflict',
410: 'Gone',
411: 'Length Required',
412: 'Precondition Failed',
413: 'Request Entity Too Large',
414: 'Request-URI Too Long',
415: 'Unsupported Media Type',
416: 'Requested Range Not Suitable',
417: 'Expectation Failed',
500: 'Internal Server Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Timeout',
505: 'HTTP Version Not Supported',
};
function createXMLHttpRequestEvent(event, target, loaded) {
const e = createEvent(event);
try {
Object.defineProperties(e, {
currentTarget: {
enumerable: true,
value: target
},
target: {
enumerable: true,
value: target
},
loaded: {
enumerable: true,
value: loaded || 0
},
// 读 Content-Range 字段,目前来说作用不大,先和 loaded 保持一致
total: {
enumerable: true,
value: loaded || 0
}
});
}
catch (err) {
// no handler
}
return e;
}
// https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
class XMLHttpRequest extends Events {
// 欺骗一些库让其认为是原生的xhr
static toString() {
return 'function XMLHttpRequest() { [native code] }';
}
toString() {
return '[object XMLHttpRequest]';
}
constructor() {
super();
_XMLHttpRequest_instances.add(this);
_XMLHttpRequest_method.set(this, void 0);
_XMLHttpRequest_url.set(this, void 0);
_XMLHttpRequest_data.set(this, void 0);
_XMLHttpRequest_status.set(this, void 0);
_XMLHttpRequest_statusText.set(this, void 0);
_XMLHttpRequest_readyState.set(this, void 0);
_XMLHttpRequest_header.set(this, void 0);
_XMLHttpRequest_responseType.set(this, void 0);
_XMLHttpRequest_resHeader.set(this, void 0);
_XMLHttpRequest_response.set(this, void 0);
_XMLHttpRequest_timeout.set(this, void 0);
_XMLHttpRequest_withCredentials.set(this, void 0);
_XMLHttpRequest_requestTask.set(this, void 0);
// 事件正常流转: loadstart => progress(可能多次) => load => loadend
// error 流转: loadstart => error => loadend
// abort 流转: loadstart => abort => loadend
// web在线测试: https://developer.mozilla.org/zh-CN/play
/** 当 request 被停止时触发,例如当程序调用 XMLHttpRequest.abort() 时 */
this.onabort = null;
/** 当 request 遭遇错误时触发 */
this.onerror = null;
/** 接收到响应数据时触发 */
this.onloadstart = null;
/** 请求成功完成时触发 */
this.onload = null;
/** 当请求结束时触发,无论请求成功 ( load) 还是失败 (abort 或 error)。 */
this.onloadend = null;
/** 在预设时间内没有接收到响应时触发 */
this.ontimeout = null;
/** 当 readyState 属性发生变化时,调用的事件处理器 */
this.onreadystatechange = null;
__classPrivateFieldSet(this, _XMLHttpRequest_method, '', "f");
__classPrivateFieldSet(this, _XMLHttpRequest_url, '', "f");
__classPrivateFieldSet(this, _XMLHttpRequest_data, null, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_status, 0, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_statusText, '', "f");
__classPrivateFieldSet(this, _XMLHttpRequest_readyState, _a.UNSENT, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_header, {
Accept: '*/*',
}, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_responseType, '', "f");
__classPrivateFieldSet(this, _XMLHttpRequest_resHeader, null, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_response, null, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_timeout, 0, "f");
/** 向前兼容,默认为 true */
__classPrivateFieldSet(this, _XMLHttpRequest_withCredentials, true, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_requestTask, null, "f");
}
addEventListener(event, callback) {
if (!isString(event))
return;
this.on(event, callback, null);
}
removeEventListener(event, callback) {
if (!isString(event))
return;
this.off(event, callback, null);
}
/**
* 对外属性和方法
*/
get timeout() {
return __classPrivateFieldGet(this, _XMLHttpRequest_timeout, "f");
}
set timeout(timeout) {
if (typeof timeout !== 'number' || !isFinite(timeout) || timeout <= 0)
return;
__classPrivateFieldSet(this, _XMLHttpRequest_timeout, timeout, "f");
}
get status() {
return __classPrivateFieldGet(this, _XMLHttpRequest_status, "f");
}
get statusText() {
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === _a.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === _a.OPENED)
return '';
return STATUS_TEXT_MAP[__classPrivateFieldGet(this, _XMLHttpRequest_status, "f") + ''] || __classPrivateFieldGet(this, _XMLHttpRequest_statusText, "f") || '';
}
get readyState() {
return __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f");
}
get responseType() {
return __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f");
}
set responseType(value) {
if (typeof value !== 'string')
return;
__classPrivateFieldSet(this, _XMLHttpRequest_responseType, value, "f");
}
get responseText() {
if (!__classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") || __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") === 'text') {
return __classPrivateFieldGet(this, _XMLHttpRequest_response, "f");
}
return null;
}
get response() {
return __classPrivateFieldGet(this, _XMLHttpRequest_response, "f");
}
get withCredentials() {
return __classPrivateFieldGet(this, _XMLHttpRequest_withCredentials, "f");
}
set withCredentials(value) {
__classPrivateFieldSet(this, _XMLHttpRequest_withCredentials, !!value, "f");
}
abort() {
if (__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f")) {
__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f").abort();
const abortEvent = createXMLHttpRequestEvent('abort', this, 0);
this.trigger('abort', abortEvent);
isFunction(this.onabort) && this.onabort(abortEvent);
}
}
getAllResponseHeaders() {
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === _a.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === _a.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")) {
return '';
}
return Object.keys(__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f"))
.map((key) => `${key}: ${__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")[key]}`)
.join('\r\n');
}
getResponseHeader(name) {
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === _a.UNSENT || __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") === _a.OPENED || !__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")) {
return null;
}
// 处理大小写不敏感
const key = Object.keys(__classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")).find((item) => item.toLowerCase() === name.toLowerCase());
const value = key ? __classPrivateFieldGet(this, _XMLHttpRequest_resHeader, "f")[key] : null;
return typeof value === 'string' ? value : null;
}
open(method, url) {
if (typeof method === 'string')
method = method.toUpperCase();
if (SUPPORT_METHOD.indexOf(method) < 0)
return;
if (!url || typeof url !== 'string')
return;
__classPrivateFieldSet(this, _XMLHttpRequest_method, method, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_url, url, "f");
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, _a.OPENED);
}
setRequestHeader(header, value) {
if (typeof header === 'string' && typeof value === 'string') {
__classPrivateFieldGet(this, _XMLHttpRequest_header, "f")[header] = value;
}
}
send(data) {
if (__classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") !== _a.OPENED)
return;
__classPrivateFieldSet(this, _XMLHttpRequest_data, data, "f");
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callRequest).call(this);
}
}
_a = XMLHttpRequest, _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) {
const hasChange = readyState !== __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_readyState, readyState, "f");
if (hasChange) {
const readystatechangeEvent = createXMLHttpRequestEvent('readystatechange', this, 0);
this.trigger('readystatechange', readystatechangeEvent);
isFunction(this.onreadystatechange) && this.onreadystatechange(readystatechangeEvent);
}
}, _XMLHttpRequest_callRequest = function _XMLHttpRequest_callRequest() {
if (!window || !window.document) {
console.warn('this page has been unloaded, so this request will be canceled.');
return;
}
if (__classPrivateFieldGet(this, _XMLHttpRequest_timeout, "f")) {
setTimeout(() => {
if (!__classPrivateFieldGet(this, _XMLHttpRequest_status, "f") && __classPrivateFieldGet(this, _XMLHttpRequest_readyState, "f") !== _a.DONE) {
// 超时
if (__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f"))
__classPrivateFieldGet(this, _XMLHttpRequest_requestTask, "f").abort();
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, _a.DONE);
const timeoutEvent = createXMLHttpRequestEvent('timeout', this, 0);
this.trigger('timeout', timeoutEvent);
isFunction(this.ontimeout) && this.ontimeout(timeoutEvent);
}
}, __classPrivateFieldGet(this, _XMLHttpRequest_timeout, "f"));
}
// 重置各种状态
__classPrivateFieldSet(this, _XMLHttpRequest_status, 0, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_statusText, '', "f");
__classPrivateFieldSet(this, _XMLHttpRequest_readyState, _a.OPENED, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_resHeader, null, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_response, null, "f");
// 补完 url
let url = __classPrivateFieldGet(this, _XMLHttpRequest_url, "f");
url = url.indexOf('//') === -1 ? window.location.origin + url : url;
// 头信息
const header = Object.assign({}, __classPrivateFieldGet(this, _XMLHttpRequest_header, "f"));
// https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
// @ts-ignore
header.cookie = window.document.$$cookie;
if (!this.withCredentials) {
// 不同源,要求 withCredentials 为 true 才携带 cookie
const { origin } = parseUrl(url);
if (origin !== window.location.origin)
delete header.cookie;
}
__classPrivateFieldSet(this, _XMLHttpRequest_requestTask, request({
url,
data: __classPrivateFieldGet(this, _XMLHttpRequest_data, "f") || {},
header,
// @ts-ignore
method: __classPrivateFieldGet(this, _XMLHttpRequest_method, "f"),
dataType: __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") === 'json' ? 'json' : 'text',
responseType: __classPrivateFieldGet(this, _XMLHttpRequest_responseType, "f") === 'arraybuffer' ? 'arraybuffer' : 'text',
success: __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestSuccess).bind(this),
fail: __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestFail).bind(this),
complete: __classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestComplete).bind(this),
}), "f");
}, _XMLHttpRequest_requestSuccess = function _XMLHttpRequest_requestSuccess({ data, statusCode, header }) {
if (!window || !window.document) {
console.warn('this page has been unloaded, so this request will be canceled.');
return;
}
__classPrivateFieldSet(this, _XMLHttpRequest_status, statusCode, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_resHeader, header, "f");
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, _a.HEADERS_RECEIVED);
if (ENABLE_COOKIE) {
// 处理 set-cookie
const setCookieStr = this.getResponseHeader('set-cookie');
if (setCookieStr && typeof setCookieStr === 'string') {
let start = 0;
let startSplit = 0;
let nextSplit = setCookieStr.indexOf(',', startSplit);
const cookies = [];
while (nextSplit >= 0) {
const lastSplitStr = setCookieStr.substring(start, nextSplit);
const splitStr = setCookieStr.substr(nextSplit);
// eslint-disable-next-line no-control-regex
if (/^,\s*([^,=;\x00-\x1F]+)=([^;\n\r\0\x00-\x1F]*).*/.test(splitStr)) {
// 分割成功,则上一片是完整 cookie
cookies.push(lastSplitStr);
start = nextSplit + 1;
}
startSplit = nextSplit + 1;
nextSplit = setCookieStr.indexOf(',', startSplit);
}
// 塞入最后一片 cookie
cookies.push(setCookieStr.substr(start));
cookies.forEach((cookie) => {
window.document.cookie = cookie;
});
}
}
// 处理返回数据
if (data) {
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, _a.LOADING);
const contentLength = Number(this.getResponseHeader('content-length') || 0);
const loadstartEvent = createXMLHttpRequestEvent('loadstart', this, contentLength);
this.trigger('loadstart', loadstartEvent);
isFunction(this.onloadstart) && this.onloadstart(loadstartEvent);
__classPrivateFieldSet(this, _XMLHttpRequest_response, data, "f");
const loadEvent = createXMLHttpRequestEvent('load', this, contentLength);
this.trigger('load', loadEvent);
isFunction(this.onload) && this.onload(loadEvent);
}
}, _XMLHttpRequest_requestFail = function _XMLHttpRequest_requestFail(err) {
// 微信小程序,无论接口返回200还是其他,响应无论是否有错误,都会进入 success 回调;只有类似超时这种请求错误才会进入 fail 回调
//
/**
* 阿里系小程序,接口返回非200状态码,会进入 fail 回调, 此时 err 对象结构如下(当错误码为 14 或 19 时,会多返回 status、data、headers。可通过这些字段获取服务端相关错误信息):
{
data: "{\"code\": 401,\"msg\":\"登录过期,请重新登录\"}"
error: 19
errorMessage: "http status error"
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', …}
originalData: "{\"code\": 401,\"msg\":\"登录过期,请重新登录\"}"
status: 401
}
*/
// 统一行为,能正常响应的,都算 success.
if (err.status) {
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_requestSuccess).call(this, {
data: err,
statusCode: err.status,
header: err.headers
});
return;
}
__classPrivateFieldSet(this, _XMLHttpRequest_status, 0, "f");
__classPrivateFieldSet(this, _XMLHttpRequest_statusText, err.errMsg || err.errorMessage, "f");
const errorEvent = createXMLHttpRequestEvent('error', this, 0);
this.trigger('error', errorEvent);
isFunction(this.onerror) && this.onerror(errorEvent);
}, _XMLHttpRequest_requestComplete = function _XMLHttpRequest_requestComplete() {
__classPrivateFieldSet(this, _XMLHttpRequest_requestTask, null, "f");
__classPrivateFieldGet(this, _XMLHttpRequest_instances, "m", _XMLHttpRequest_callReadyStateChange).call(this, _a.DONE);
if (__classPrivateFieldGet(this, _XMLHttpRequest_status, "f")) {
const contentLength = Number(this.getResponseHeader('content-length') || 0);
const loadendEvent = createXMLHttpRequestEvent('loadend', this, contentLength);
this.trigger('loadend', loadendEvent);
isFunction(this.onloadend) && this.onloadend(loadendEvent);
}
};
XMLHttpRequest.UNSENT = 0;
XMLHttpRequest.OPENED = 1;
XMLHttpRequest.HEADERS_RECEIVED = 2;
XMLHttpRequest.LOADING = 3;
XMLHttpRequest.DONE = 4;
if (process.env.TARO_PLATFORM !== 'web') {
if (ENABLE_COOKIE) {
const _cookie = createCookieInstance();
Object.defineProperties(document, {
URL: {
get() {
if (this.defaultView)
return this.defaultView.location.href;
return '';
},
},
cookie: {
get() {
return _cookie.getCookie(this.URL);
},
set(value) {
if (!value || typeof value !== 'string')
return;
_cookie.setCookie(value, this.URL);
},
},
/** 获取完整的 cookie,包括 httpOnly 也能获取到 */
$$cookie: {
get() {
return _cookie.getCookie(this.URL, true);
},
}
});
}
window.XMLHttpRequest = XMLHttpRequest;
}
export { Cookie, XMLHttpRequest };
//# sourceMappingURL=runtime.js.map