HTML5 `XHR2`:二进制数据传输与上传进度监控

HTML5 XHR2:让你的浏览器不再“慢吞吞”——二进制数据传输与上传进度监控

各位看官,今天咱们聊聊HTML5里一个很实用,但可能被不少人忽略的家伙——XMLHttpRequest Level 2,简称XHR2。 别一听“XMLHttpRequest”就觉得高大上,其实它就是个HTTP请求的客户端,负责在浏览器和服务器之间搬运数据。只不过这位“二代”可比“一代”强太多了,多了很多实用技能,比如二进制数据传输和上传进度监控。

想象一下,你辛辛苦苦拍了一张美美的照片,想上传到朋友圈,结果半天没反应,浏览器就像个便秘的老大爷,吭哧吭哧半天也挤不出来。心情瞬间down到谷底,恨不得把手机砸了。这很大程度上就是因为你的上传姿势不对!用对了XHR2,就能让你的上传过程像开了火箭一样,嗖嗖的!

一、告别字符串的束缚:二进制数据,才是王道!

在XHR1时代,我们只能传输文本数据,也就是字符串。这就像用驴车拉火箭,速度慢不说,还容易把火箭给颠散架了。而XHR2的出现,让我们可以直接传输二进制数据,比如图片、音频、视频等等。

为什么要用二进制数据?因为二进制数据是计算机最原始的表达方式,传输效率最高。字符串在传输之前需要编码,接收之后需要解码,这中间就浪费了不少时间和资源。直接传输二进制数据,就能省去这些中间环节,速度自然就快了。

那么,问题来了,我们怎么把这些图片、音频、视频变成二进制数据呢?别慌,HTML5早就为我们准备好了“神器”——BlobArrayBuffer

  • Blob: 可以理解为一个指向二进制数据的指针,它包含数据的类型(MIME类型)和大小等信息。你可以从文件、canvas、甚至其他Blob对象创建Blob对象。

    // 从文件创建Blob对象
    const fileInput = document.querySelector('input[type="file"]');
    fileInput.addEventListener('change', function() {
        const file = this.files[0];
        const blob = new Blob([file], { type: file.type });
        console.log(blob); // Blob {size: 123456, type: "image/jpeg"}
    });
    
    // 从canvas创建Blob对象
    const canvas = document.getElementById('myCanvas');
    canvas.toBlob(function(blob) {
        console.log(blob); // Blob {size: 789012, type: "image/png"}
    }, 'image/png');
  • ArrayBuffer: 则是一块原始的二进制数据缓冲区,它没有类型信息,需要通过TypedArray(比如Uint8ArrayInt32Array等)来解读。

    // 创建ArrayBuffer
    const buffer = new ArrayBuffer(16); // 创建一个16字节的缓冲区
    
    // 使用Uint8Array解读ArrayBuffer
    const uint8Array = new Uint8Array(buffer);
    uint8Array[0] = 255; // 设置第一个字节的值为255
    console.log(uint8Array); // Uint8Array(16) [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

有了Blob和ArrayBuffer,我们就可以把各种数据转换成二进制形式,然后通过XHR2进行传输了。

二、XHR2的“正确打开方式”:发送二进制数据

现在,让我们来看看如何使用XHR2发送二进制数据。

const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);

// 设置响应类型为blob,接收服务器返回的二进制数据
xhr.responseType = 'blob';

xhr.onload = function() {
    if (xhr.status === 200) {
        const blob = xhr.response;
        // 对接收到的blob数据进行处理,比如显示图片
        const imageUrl = URL.createObjectURL(blob);
        const img = document.createElement('img');
        img.src = imageUrl;
        document.body.appendChild(img);
    } else {
        console.error('上传失败:' + xhr.status);
    }
};

// 发送Blob对象
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', function() {
    const file = this.files[0];
    const blob = new Blob([file], { type: file.type });
    xhr.send(blob);
});

这段代码的关键在于:

  1. 设置xhr.responseType = 'blob',告诉浏览器我们期望接收到的是二进制数据。
  2. 使用xhr.send(blob)发送Blob对象。

服务器端也需要进行相应的处理,接收二进制数据并进行保存。

三、掌控全局:上传进度监控,不再盲等!

上传过程中,最让人抓狂的就是等待。尤其是上传大文件的时候,进度条像蜗牛一样慢慢爬,让人怀疑是不是网络断了。有了XHR2的上传进度监控,我们就能实时了解上传进度,不再盲等。

const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);

// 监听上传进度事件
xhr.upload.addEventListener('progress', function(event) {
    if (event.lengthComputable) {
        const percentComplete = (event.loaded / event.total) * 100;
        console.log('上传进度:' + percentComplete + '%');
        // 更新进度条
        document.getElementById('progressBar').value = percentComplete;
    }
});

xhr.onload = function() {
    if (xhr.status === 200) {
        console.log('上传成功!');
    } else {
        console.error('上传失败:' + xhr.status);
    }
};

// 发送Blob对象
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', function() {
    const file = this.files[0];
    const blob = new Blob([file], { type: file.type });
    xhr.send(blob);
});

这段代码中,我们监听了xhr.upload.addEventListener('progress', ...)事件,这个事件会在上传过程中不断触发,每次触发都会告诉我们已经上传了多少数据(event.loaded)和总共需要上传多少数据(event.total)。通过计算percentComplete = (event.loaded / event.total) * 100,我们就能得到上传的百分比,然后更新进度条。

需要注意的是,event.lengthComputable属性表示服务器是否提供了总文件大小的信息。如果服务器没有提供,event.lengthComputable的值就为false,我们就无法计算上传进度。

四、注意事项:跨域,永远的痛!

在使用XHR2进行跨域请求时,需要注意跨域问题。浏览器出于安全考虑,会阻止跨域请求。要解决跨域问题,需要在服务器端设置Access-Control-Allow-Origin响应头。

Access-Control-Allow-Origin: *  // 允许所有域名访问
Access-Control-Allow-Origin: http://example.com  // 只允许example.com域名访问

五、总结:XHR2,让你的网页更“丝滑”!

XHR2的二进制数据传输和上传进度监控功能,极大地提升了Web应用的性能和用户体验。它让我们可以更高效地传输各种数据,并实时了解上传进度,不再盲等。

想象一下,你开发了一个在线视频编辑工具,用户可以上传自己的视频进行编辑。如果使用XHR1,上传速度慢不说,用户还不知道上传进度,体验简直糟糕透顶。而使用XHR2,上传速度快如闪电,用户还能实时看到上传进度,心情瞬间舒畅!

所以,各位看官,赶紧把XHR2用起来吧,让你的网页更“丝滑”,让你的用户更满意!相信我,用了XHR2,你再也不想回到从前了!就像用了电动牙刷,再也不想用普通牙刷了,手动狗头。

最后,希望这篇文章能让你对HTML5 XHR2有更深入的了解。记住,技术是为了服务于人的,我们要用技术创造更美好的用户体验。

祝大家编码愉快,Bug远离!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注