@mptool/net
Networking framework for mini-programs, about 26.2 kB.
request and createRequest
The framework provides a createRequest factory and a global request method, along with the commonly used Headers and URLSearchParams.
createRequest is a factory function that returns a request method and a cookieStore, and lets you control the default behavior with the following options. These options are applied to every request unless you override them per request:
server: the default domain to accessredirect: the default redirect policy; supportsfollowandmanual, and defaults tofollowenableCache: enables cacheenableChunked: enables transfer-encoding chunkedenableHttp2: enables HTTP/2enableHttpDNS: enables the HTTPDNS service. When enabled, you must also providehttpDNSServiceId. For details, see HTTPDNShttpDNSServiceId: the HTTPDNS service provider ID. For details, see HTTPDNSenableQuic: enables QUICforceCellularNetwork: forces requests to use the cellular networktimeout: timeout in milliseconds. When omitted, WeChat'snetworkTimeoutconfiguration applies (60000 ms by default)retry: the default retry configuration; see Cancellation, timeouts and retries below for its shape
The default request, as well as the request generated by createRequest, accepts two arguments: the request URL and RequestOptions. It supports the options of wx.request (except url / method / header / data / success / fail).
When using it, avoid the url, data and header options, and do not pass success / fail. The URL is already provided as the first argument, while the replacements for the latter two are body and headers. success / fail are taken over internally to resolve / reject the Promise and write back cookies from the response; they are overwritten even if you force them in at runtime.
request automatically saves cookies from responses and attaches the corresponding cookies to requests. It also enhances the following options:
methodadditionally accepts lowercase method namesbodyadditionally acceptsURLSearchParamsandnull. TheURLSearchParamshere must be the class exported by this package to be recognized; when using aURLSearchParamsfrom another source, callbody.toString()first and pass the string.headersadditionally acceptsHeadersinstances and arrays of header entriescookieScopeis new and controls the scope of the attached cookies (defaults tourl); it must include a domain (an absolute URL or a domain, not a bare path such as"/api")cookieStoreis new and controls theCookieStoreinstance read from during requests and written to on responses (defaults to the built-in global instance)
When wx.env.DEBUG is enabled, request outputs debug logs, but the logs are redacted: Cookie prints names only (not values), and the values of sensitive headers such as Cookie / Authorization are replaced with <redacted>; response bodies are logged only by type/length or truncated to 512 characters, so complete responses and credentials are never written to the logs.
The request URL must be absolute (https://example.com/api or //example.com/api); relative URLs are invalid calls and throw a TypeError before the request is sent. With a createRequest() factory you can pass "/api" directly, and the factory prepends server automatically.
Info
On WeChat base library 3.2.3 and above, you can set redirect: manual for each request. Responses with status code 301 are then preserved as-is instead of being followed immediately, and cookies set by redirect responses can be recorded.
The framework cannot parse cookies in redirect responses, so requests made by other base library versions, or without the redirect option, are still limited.
request returns a Promise. You can use then to get the response, or catch to handle errors.
The return value is an ordinary Promise with cancellation capabilities attached:
abort(): cancels this request (including a pending retry); idempotenttask: the underlyingRequestTaskfor the current attempt
const req = request("https://example.com/api/user");
req.abort(); // Cancel the request
await req; // It can still be used as a normal PromiseRequest options additionally support:
cancelKey: a cancellation group key for batch cancellation withcreateRequest().abort(key)onTask: receives theRequestTaskof each attempt (progress / headers events)signal: a cancellation signal; only{ aborted: boolean }is required (optionally withaddEventListener)retry: the retry configuration for this request;falsedisables retries
Cancellation, timeouts and retries
const api = createRequest({
server: "https://example.com",
timeout: 15000,
retry: {
attempts: 3, // Including the first attempt
delay: 300,
maxDelay: 3000,
methods: ["GET", "HEAD"], // Only idempotent methods are retried by default
statusCodes: [408, 429, 500, 502, 503, 504],
rejectOnHttpError: false, // Keep resolving for every status code by default
onRetry: ({ attempt, delay, error }) => {},
},
});
// Cancel in batches when the page unloads
api.request("/user", { cancelKey: "page:user" });
onUnload(() => api.abort("page:user")); // Or api.abortAll()- If
timeoutis omitted, WeChat'snetworkTimeoutapplies (60 seconds by default); the framework does not impose its own default; - Retries are disabled by default. Retries only apply to methods listed in
methods, andabortstops retries immediately; - The Cookie header is recalculated for every attempt;
- Failures are normalized to
MpError(aRequestErrorsubclass), which additionally exposestype: "abort" | "timeout" | "network" | "http"for distinction;responseHandler/errorHandlerare called only once for the final result.
Info
The framework enables enableHttp2 and useHighPerformanceMode by default. To disable them, pass the corresponding options on an individual request to override them.
A successful request (any status code) triggers the .then callback and returns an object containing the following information:
- status: the response status code as a number
- headers: a
Headersinstance - data: the response data
If the request fails (due to the base library, the underlying layer or the network), the .catch path runs and returns an MpError. You can get the error message via the message property, or the error code via the code property.
Cookie
The framework provides Cookie for storing and serializing cookie data.
The Cookie class has the following members:
Instance properties:
name: string: cookie namevalue: string: cookie valuedomain: string: cookie domainpath: string: cookie pathcreatedAt: number: creation time (millisecond timestamp), used for RFC 6265 cookie orderingexpires: Date | "session" | "outdate": expiration timehttpOnly: boolean: whether the cookie is used only over HTTP
Methods:
isExpired(): boolean: checks whether the cookie has expiredisPersistence(): boolean: checks whether the cookie can be persistedisDomainMatched(domain: string): boolean: checks whether the cookie matches a domaindomain: the domain
isPathMatched(path: string): boolean: checks whether the cookie matches a pathpath: the path
toString(): string: converts the cookie to a stringtoJSON(): CookieType: serializes the cookie to an object
CookieType is the serialized cookie object type and contains the following fields:
name: cookie namevalue: cookie valuepath: cookie pathcreatedAt: creation time (millisecond timestamp)expires: expiration time (aDateobject)maxAge: maximum lifetime (seconds)domain: cookie domainsecure: whether the cookie is sent only over HTTPS (mini-programs support HTTPS only, and real devices can always send it; it is skipped only forhttp://debugging URLs)httpOnly: whether the cookie is used only over HTTPsameSite: the SameSite attribute (lax/strict/none), persisted with the cookie
name and value are required; all other fields are optional.
CookieStore
The framework provides CookieStore for storing cookies. After creating a CookieStore instance, you can read and write cookies through it:
const cookieStore = new CookieStore(key);key is optional; when omitted, the default is used. We recommend initializing a global instance in app.js and mounting it on the App object for global use. If different subpackages need isolation, initialize one instance per subpackage.
Creating multiple instances with the same key causes problems
A CookieStore instance provides the following methods:
get(name, options): gets a cookiegetValue(name, options): gets a cookie valuehas(name, options): checks whether a cookie existsset(options): sets a cookiedelete(name, domain?, path?): deletes the specified cookie; whenpathis omitted, deletes cookies with that name on all pathslist(): gets all cookies grouped by domaingetCookies(options): gets cookies that match the conditionsgetAllCookies(): gets all cookiesgetCookiesMap(options): gets a key/value Map of cookies that match the conditionsapply(cookies): applies cookies to the storeclear(domain?, exact=false): clears all cookies underdomain(or only the exactdomainwhenexactistrue); when domain is omitted, clears all cookiesapplyHeader(header, domainOrURL): applies cookies from a headerapplyResponse(response, domainOrURL): applies cookies from a response, whereresponseis thesuccesscallback object ofwx.requestgetHeader(options): gets the cookie header
Cookies are stored as (name, domain, path) triples, so cookies with the same name but different paths can coexist. getCookies() sorts according to RFC 6265 §5.4: a longer path comes first, and when path lengths are equal, an earlier creation time comes first; get() / getValue() return the first match in that order, and getHeader() joins cookies with the same name in the same order.
Storage reads and writes are optimized: cookies are loaded from Storage only on the first read or write (importing @mptool/net does not trigger a synchronous read at startup); multiple set / delete / clear / apply calls within the same microtask are merged into a single wx.setStorageSync write. To limit bloat caused by abnormal responses, a single cookie larger than 4096 bytes is dropped; a domain keeps at most 50 cookies and the total is capped at 3000 (the minimum capacity recommended by RFC 6265 §6.1). When the limit is exceeded, the cookies with the earliest creation time are evicted.
options is optional and supports the following:
an object with any combination of the following keys
domain: specifies the domainpath: specifies the path
a URL string