发送和接收二进制数据

XMLHttpRequest 对象的responseType属性可以设置为更改服务器期望的响应类型。可能的值为空字符串(默认值)、"arraybuffer""blob""document""json""text"response属性将根据responseType包含实体主体,作为ArrayBufferBlobDocumentJSON或字符串。如果请求未完成或未成功,则为null

此示例将图像读取为二进制文件,并从原始字节创建 8 位无符号整数数组。请注意,这不会解码图像并读取像素。您将需要一个png 解码库来实现。

js
const req = new XMLHttpRequest();
req.open("GET", "/myfile.png", true);
req.responseType = "arraybuffer";

req.onload = (event) => {
  const arrayBuffer = req.response; // Note: not req.responseText
  if (arrayBuffer) {
    const byteArray = new Uint8Array(arrayBuffer);
    byteArray.forEach((element, index) => {
      // do something with each byte in the array
    });
  }
};

req.send(null);

您还可以通过将字符串"blob"设置为responseType属性来将二进制文件读取为Blob

js
const req = new XMLHttpRequest();
req.open("GET", "/myfile.png", true);
req.responseType = "blob";

req.onload = (event) => {
  const blob = req.response;
  // ...
};

req.send();

在旧版浏览器中接收二进制数据

下面显示的loadBinaryResource()函数从指定的 URL 加载二进制数据,并将其返回给调用方。

js
function loadBinaryResource(url) {
  const req = new XMLHttpRequest();
  req.open("GET", url, false);

  // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
  req.overrideMimeType("text/plain; charset=x-user-defined");
  req.send(null);
  return req.status === 200 ? req.responseText : "";
}

overrideMimeType函数是实现这一功能的关键,它强制浏览器将数据视为纯文本,使用用户定义的字符集。这告诉浏览器不要解析它,并让字节未经处理地传递。

js
const filestream = loadBinaryResource(url);
const abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)

上面的示例获取加载的二进制数据中偏移量x处的字节。x的有效范围是从 0 到filestream.length-1

有关详细信息,请参阅使用 XMLHttpRequest 下载二进制流

发送二进制数据

XMLHttpRequest 的send方法已扩展为通过接受ArrayBufferBlobFile对象来轻松传输二进制数据。

以下示例动态创建了一个文本文件,并使用POST方法将“文件”发送到服务器。此示例使用纯文本,但您可以想象数据是二进制文件。

js
const req = new XMLHttpRequest();
req.open("POST", url, true);
req.onload = (event) => {
  // Uploaded
};

const blob = new Blob(["abc123"], { type: "text/plain" });

req.send(blob);

发送类型化数组作为二进制数据

您也可以将 JavaScript 类型化数组作为二进制数据发送。

js
// Create a new array with fake data (Consecutive numbers (0 - 255), looping back to 0)
const array = new Uint8Array(512).map((v, i) => i);

const xhr = new XMLHttpRequest();
xhr.open("POST", url, false);
xhr.send(array);

这正在构建一个 512 字节的 8 位整数数组并发送它;当然,您可以使用任何您想要的二进制数据。

提交表单和上传文件

请参阅FormData