npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mphttpx

v2.2.1

Published

A polyfill for mini-program.

Readme

MPHTTPX 中文文档

mphttpx旨在为小程序提供与浏览器一致的请求开发体验,通过引入此库即可在小程序中使用XMLHttpRequest、fetch和FormData等浏览器请求相关功能。

目录

功能

  • TextEncoder
  • TextDecoder
  • Blob
  • File
  • FileReader
  • URLSearchParams
  • FormData
  • fetch
  • Headers
  • Request
  • Response
  • AbortController
  • EventTarget
  • XMLHttpRequest (小程序)
  • WebSocket (小程序, 从1.1.0之后)
  • 支持 tree-shaking (从2.0.0之后)

安装

npm install mphttpx

小程序支持情况

| 微信 | 支付宝 | 百度 | 抖音 | QQ | 快手 | 京东 | 小红书 | |:---:|:------:|:----:|:---:|:--:|:----:|:---:|:------:| | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |

注意:在现代浏览器中,并不需要这些填充功能,在浏览器中从mphttpx导入的函数会直接返回浏览器本地的函数。

使用

注意:mphttpx中所有的模块都有一个与之对应的以字母P结尾的版本,两者的区别在于以字母P结尾的版本是polyfill的。

举个例子:

// mphttpx不对globalThis做任何修改
import { TextEncoder } from "mphttpx";  // 优先返回全局对象,如果不存在则返回polyfill实现
import { TextEncoderP } from "mphttpx"; // 直接返回polyfill实现

TextEncoder

示例

import { TextEncoder } from "mphttpx";

const encoder = new TextEncoder();
const encoded = encoder.encode("€");

console.log(encoded); // Uint8Array(3) [226, 130, 172]

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | encoding | ✔ | utf-8 |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | encode(string) | ✔ | | encodeInto(string, uint8Array) | ✔ |

TextDecoder

示例

import { TextDecoder } from "mphttpx";

const utf8decoder = new TextDecoder(); // 默认 'utf-8'
const encodedText = new Uint8Array([240, 160, 174, 183]);

console.log(utf8decoder.decode(encodedText)); // 𠮷

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | encoding | ✔ | 仅utf-8 | | fatal | ✔ | | ignoreBOM | ✔ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | decode() | ✔ | | decode(buffer) | ✔ | | decode(buffer, options) | ✔ |

Blob

示例

创建blob

import { Blob, fetch } from "mphttpx";

const obj = { hello: "world" };
const blob = new Blob([JSON.stringify(obj, null, 2)], {
    type: "application/json",
});

const another_blob = new Blob(["Hello, World!"], {
    type: "text/plain"
});

fetch("https://www.test.com/blob", {
    method: "POST",
    body: another_blob,
});

从blob提取数据

import { Blob, FileReader, fetch } from "mphttpx";

const blob = new Blob([JSON.stringify({ foo: "bar" })], {
    type: "application/json",
});

const reader = new FileReader();
reader.addEventListener("loadend", () => {
  // reader.result中包含了ArrayBuffer数据格式的内容 
});
reader.readAsArrayBuffer(blob);

fetch("https://www.test.com/blob", {
    method: "POST",
    body: blob,
})
    .then(r => r.blob())
    .then(r => {
        const reader2 = new FileReader();
        reader2.onload = () => {
            // reader2.result
        }
        reader2.readAsDataURL(r);   // base64
    });

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | size | ✔ | | type | ✔ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | arrayBuffer() | ✔ | | bytes() | ✔ | | slice() | ✔ | | slice(start) | ✔ | | slice(start, end) | ✔ | | slice(start, end, contentType) | ✔ | | stream() | ✖ | | text() | ✔ |

File

示例

import { File } from "mphttpx";

const file = new File(["foo"], "foo.txt", {
    type: "text/plain",
});

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | lastModified | ✔ | | name | ✔ | | webkitRelativePath | ✖ |

FileReader

示例

import { File, FileReader } from "mphttpx";

const file = new File([JSON.stringify({ foo: "bar" })], "test.json", {
    type: "application/json",
});

// 读取file
const reader = new FileReader();
reader.onload = () => {
    console.log(reader.result);
};
reader.readAsText(file);

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | error | ✔ | | readyState | ✔ | | result | ✔ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | abort() | ✔ | 模拟实现 | | readAsArrayBuffer() | ✔ | | readAsBinaryString() | ✔ | | readAsDataURL() | ✔ | | readAsText() | ✔ | 仅utf-8 |

URLSearchParams

示例

import { URLSearchParams, fetch } from "mphttpx";

const paramsString = "q=URLUtils.searchParams&topic=api";
const searchParams = new URLSearchParams(paramsString);

// 迭代搜索参数
for (const p of searchParams) {
    console.log(p);
}

console.log(searchParams.has("topic")); // true
console.log(searchParams.has("topic", "fish")); // false
console.log(searchParams.get("topic") === "api"); // true
console.log(searchParams.getAll("topic")); // ["api"]
console.log(searchParams.get("foo") === null); // true
console.log(searchParams.append("topic", "webdev"));
console.log(searchParams.toString()); // "q=URLUtils.searchParams&topic=api&topic=webdev"
console.log(searchParams.set("topic", "More webdev"));
console.log(searchParams.toString()); // "q=URLUtils.searchParams&topic=More+webdev"
console.log(searchParams.delete("topic"));
console.log(searchParams.toString()); // "q=URLUtils.searchParams"

// GET
fetch("https://www.test.com/get" + `?${searchParams.toString()}`);

// POST
fetch("https://www.test.com/post", {
    method: "POST",
    body: searchParams,
});

搜索参数也可以通过对象构造

import { URLSearchParams } from "mphttpx";

const paramsObj = { foo: "bar", baz: "bar" };
const searchParams = new URLSearchParams(paramsObj);

console.log(searchParams.toString()); // "foo=bar&baz=bar"
console.log(searchParams.has("foo")); // true
console.log(searchParams.get("foo")); // "bar"

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | size | ✔ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | append(name, value) | ✔ | | delete(name) | ✔ | | delete(name, value) | ✔ | | entries() | ✔ | | forEach(callback) | ✔ | | forEach(callback, thisArg) | ✔ | | get(name) | ✔ | | getAll(name) | ✔ | | has(name) | ✔ | | has(name, value) | ✔ | | keys() | ✔ | | set(name, value) | ✔ | | sort() | ✔ | | toString() | ✔ | | values() | ✔ |

FormData

示例

import { FormData, fetch } from "mphttpx";

const formData = new FormData();
formData.append("username", "Chris");

const file = new File(["Hello, World!"], "file.txt", {
    type: "text/plain",
});
formData.append("file", file);

fetch("https://www.test.com/formdata", {
    method: "POST",
    body: formData,
});

兼容性

构造函数

| 构造函数 | 可用性 | 描述 | | ----------- | --------- | -------------| | new FormData() | ✔ | | new FormData(form) | ✖ | | new FormData(form, submitter) | ✖ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | append(name, value) | ✔ | | append(name, value, filename) | ✔ | | delete(name) | ✔ | | entries() | ✔ | | get(name) | ✔ | | getAll(name) | ✔ | | has(name) | ✔ | | keys() | ✔ | | set(name, value) | ✔ | | set(name, value, filename) | ✔ | | values() | ✔ |

fetch

示例

import { fetch } from "mphttpx";

fetch("http://example.com/movies.json")
    .then((response) => response.json())
    .then((data) => console.log(data));

通过fetch发送JSON数据

import { fetch } from "mphttpx";

const data = { username: "example" };

fetch("https://example.com/profile", {
    method: "POST", // 或 'PUT'
    headers: {
        "Content-Type": "application/json",
    },
    body: JSON.stringify(data),
})
    .then((response) => response.json())
    .then((data) => {
        console.log("Success:", data);
    })
    .catch((error) => {
        console.error("Error:", error);
    });

上传文件

import { fetch, File, FormData } from "mphttpx";

const formData = new FormData();

formData.append("username", "abc123");
formData.append("file", new File(["foo"], "foo.txt", { type: "text/plain" }));

fetch("https://example.com/profile/avatar", {
    method: "PUT",
    body: formData,
})
    .then((response) => response.json())
    .then((result) => {
        console.log("Success:", result);
    })
    .catch((error) => {
        console.error("Error:", error);
    });

注意:fetch基于下层XMLHttpRequest实现,且这个下层实现是可以替换的。

import { setXMLHttpRequest } from "mphttpx";
setXMLHttpRequest(another_XMLHttpRequest);  // 自定义XMLHttpRequest实现

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | fetch(resource) | ✔ | | fetch(resource, options) | ✔ |

兼容性

参考下方Request

Request

示例

import { fetch, Request } from "mphttpx";

const request = new Request("https://www.mozilla.org/favicon.ico");

const url = request.url;
const method = request.method;
const credentials = request.credentials;

fetch(request)
    .then((response) => response.blob())
    .then((blob) => {
        console.log(blob);
    });
import { fetch, Request } from "mphttpx";

const request = new Request("https://example.com", {
    method: "POST",
    body: '{"foo": "bar"}',
});

const url = request.url;
const method = request.method;
const credentials = request.credentials;
const bodyUsed = request.bodyUsed;

fetch(request)
    .then((response) => {
        if (response.status === 200) {
            return response.json();
        } else {
            throw new Error("Something went wrong on API server!");
        }
    })
    .then((response) => {
        console.debug(response);
        // …
    })
    .catch((error) => {
        console.error(error);
    });

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | body | ✖ | | bodyUsed | ✔ | | cache | ✔ | | credentials | ✔ | | destination | ✖ | | headers | ✔ | | integrity | ✖ | | keepalive | ✖ | | method | ✔ | | mode | ✖ | | redirect | ✖ | | referrer | ✖ | | referrerPolicy | ✖ | | signal | ✔ | | url | ✔ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | arrayBuffer() | ✔ | | blob() | ✔ | | bytes() | ✔ | | clone() | ✔ | | formData() | ✔ | | json() | ✔ | | text() | ✔ |

Response

示例

import { Response, Blob, fetch } from "mphttpx";

const myBlob = new Blob();
const myOptions = { status: 200, statusText: "SuperSmashingGreat!" };
const myResponse = new Response(myBlob, myOptions);

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | body | ✖ | | bodyUsed | ✔ | | headers | ✔ | | ok | ✔ | | redirected | ✖ | | status | ✔ | | statusText | ✔ | | type | ✖ | | url | ✔ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | arrayBuffer() | ✔ | | blob() | ✔ | | bytes() | ✔ | | clone() | ✔ | | formData() | ✔ | | json() | ✔ | | text() | ✔ |

Headers

示例

import { Headers, fetch } from "mphttpx";

const myHeaders = new Headers();

myHeaders.append("Content-Type", "text/plain");
myHeaders.get("Content-Type"); // 应当返回'text/plain'

fetch("https://www.test.com/headers", {
    headers: myHeaders,
});

通过传递数组的数组或普通对象也可进行构造:

import { Headers } from "mphttpx";

let myHeaders = new Headers({
    "Content-Type": "text/plain",
});

// 或:使用数组的数组:
myHeaders = new Headers([["Content-Type", "text/plain"]]);

myHeaders.get("Content-Type"); // 应当返回'text/plain'

兼容性

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | append(name, value) | ✔ | | delete(name) | ✔ | | entries() | ✔ | | forEach(callbackFn) | ✔ | | forEach(callbackFn, thisArg) | ✔ | | get(name) | ✔ | | getSetCookie() | ✔ | | has(name) | ✔ | | keys() | ✔ | | set(name, value) | ✔ | | values() | ✔ |

AbortController

示例

import { AbortController, fetch } from "mphttpx";

const controller = new AbortController();

fetch("https://www.test.com/abort", {
    signal: controller.signal,
});
import { AbortController, AbortSignal, Request, fetch } from "mphttpx";

async function get() {
    const controller = new AbortController();
    const request = new Request("https://example.org/get", {
        signal: controller.signal,
    });

    const response = await fetch(request);
    controller.abort();
    // 下一行将会抛出`AbortError`异常
    const text = await response.text();
    console.log(text);
}

兼容性

AbortController属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | signal | ✔ |

AbortController方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | abort() | ✔ | | abort(reason) | ✔ |

AbortSignal属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | aborted | ✔ | | reason | ✔ |

AbortSignal方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | throwIfAborted() | ✔ |

EventTarget

示例

import { EventTarget, Event, CustomEvent } from "mphttpx";

const target = new EventTarget();

target.addEventListener("foo", function (evt) {
    console.log(evt);
});

const evt = new Event("foo");
target.dispatchEvent(evt);

target.addEventListener("animalfound", function (evt) {
    console.log(evt.detail.name);
});

const catFound = new CustomEvent("animalfound", {
    detail: {
        name: "cat",
    },
});
target.dispatchEvent(catFound);

兼容性

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | addEventListener(type, listener) | ✔ | | addEventListener(type, listener, options) | ✔ | | addEventListener(type, listener, useCapture) | ✔ | | dispatchEvent(event) | ✔ | | removeEventListener(type, listener) | ✔ | | removeEventListener(type, listener, options) | ✔ | | removeEventListener(type, listener, useCapture) | ✔ |

XMLHttpRequest (小程序)

示例

GET

import { XMLHttpRequest } from "mphttpx";

const xhr = new XMLHttpRequest();
xhr.open("GET", "https://example.com/server?foo=bar&lorem=ipsum");

xhr.onload = () => {
    // 请求完成。在此处理业务。
};

xhr.send();

POST

import { XMLHttpRequest } from "mphttpx";

const xhr = new XMLHttpRequest();
xhr.open("POST", "https://example.com/server");

// 在请求时携带合适的头信息
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");

xhr.onreadystatechange = () => {
    // 当状态变化时调用函数
    if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
        // 请求完成。在此处理业务。
    }
};

xhr.send(JSON.stringify({ foo: "bar", lorem: "ipsum" }));

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | readyState | ✔ | 2, 3: 模拟实现 | | response | ✔ | | responseText | ✔ | | responseType | ✔ | 不支持"document" | | responseURL | ✔ | responseURL将原样返回请求中的URL地址 | | responseXML | ✖ | | status | ✔ | | statusText | ✔ | | timeout | ✔ | 该值必须小于小程序的默认超时时间 | | upload | ✔ | 模拟实现 | | withCredentials | ✖ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | abort() | ✔ | | getAllResponseHeaders() | ✔ | | getResponseHeader(headerName) | ✔ | | open(method, url) | ✔ | | open(method, url, async) | ✔ | | open(method, url, async, user) | ✔ | | open(method, url, async, user, password) | ✔ | | overrideMimeType(mimeType) | ✖ | | send() | ✔ | | send(body) | ✔ | | setRequestHeader(header, value) | ✔ |

WebSocket (小程序, 从1.1.0之后)

示例

import { WebSocket } from "mphttpx";

// 创建WebSocket连接
const socket = new WebSocket("wss://example.com:8080");

// 将二进制类型从"blob"改为"arraybuffer"
socket.binaryType = "arraybuffer";

// 监听消息
socket.addEventListener("message", (event) => {
    if (event.data instanceof ArrayBuffer) {
        // 二进制帧
        const view = new DataView(event.data);
        console.log(view.getInt32(0));
    } else {
        // 文本帧
        console.log(event.data);
    }
});

兼容性

属性

| 属性 | 可用性 | 描述 | | --------- | --------- | -------------| | binaryType | ✔ | | bufferedAmount | ✖ | | extensions | ✖ | | protocol | ✔ | | readyState | ✔ | | url | ✔ |

方法

| 方法 | 可用性 | 描述 | | ------- | --------- | -------------| | close() | ✔ | | close(code) | ✔ | | close(code, reason) | ✔ | | send(data) | ✔ |

自动导入

查看unplugin-auto-import获取更多信息。

// 仅参考
AutoImport({
    // 其他配置

    imports: [
        // 其他导入

        {
            "mphttpx": [
                "TextEncoder",
                "TextDecoder",

                "Blob",
                "File",
                "FileReader",

                "URLSearchParams",
                "FormData",

                "fetch",
                "Headers",
                "Request",
                "Response",

                "AbortController",
                "AbortSignal",

                "EventTarget",
                "Event",
                "CustomEvent",

                "XMLHttpRequest",   // 小程序
                "WebSocket",        // 小程序
            ],
        },

        // 其他导入
    ],

    // 其他配置
});

注意(UniApp开发者):如果你的项目是通过HBuilderX以老式Vue2为模板创建的,尝试安装老版本的unplugin-auto-import以支持CMD模块,比如0.16.7版本。

UniApp & Taro

import { setRequest } from "mphttpx";
import { setConnectSocket } from "mphttpx";

setRequest(uni.request);
// setRequest(Taro.request);

setConnectSocket(uni.connectSocket);
// setConnectSocket(Taro.connectSocket);

注意:使用UniApp或Taro时,如果fetch, XMLHttpRequestWebSocket无法正常工作,尝试显式设置request/connectSocket函数。

Node.js

npm install xhr2
import XMLHttpRequest from "xhr2";
import { setXMLHttpRequest } from "mphttpx";

setXMLHttpRequest(XMLHttpRequest);

开源协议

MIT