不使用onprogress事件实现上传进度条,求Edge兼容替代方案
Hey, I totally get the frustration with Edge 15's broken xhr.upload.progress implementation—having it fire only once at the end is a real pain, especially when all the popular upload libraries rely on that behavior. Let’s dive into the non-Flash approaches developers used before progress listeners were widely available, plus some modern fixes for your Edge issue:
1. 分块上传(Chunked Upload)
This is hands down the most robust alternative, and it’s actually a modern best practice for large file uploads too. Here’s how it works:
- Split your file into smaller chunks (say 1MB each) using
File.slice()to create Blob objects for each piece. - Send each chunk to your server via separate POST requests, including metadata like the chunk index and total number of chunks.
- After each chunk successfully uploads, calculate the percentage of the total file that’s been transferred and update your progress bar.
- On the server side, you’ll need to assemble these chunks back into the full file once all are received.
Pros: No dependency on the broken progress event, supports resumable uploads if a chunk fails, and works reliably across all modern browsers (including Edge).
Cons: Requires server-side logic to handle chunk assembly and track upload state.
2. Server-Side Polling for Upload Status
If you can’t modify your server to handle chunked uploads, polling is a simpler (though less efficient) workaround:
- When you start the upload, generate a unique ID for the file (like an MD5 hash or random string) and send it along with the upload request.
- Use
setIntervalon the client to send periodic GET requests to your server, asking for the number of bytes already uploaded for that unique ID. - Calculate the progress percentage using the total file size and the server’s response, then update your progress bar accordingly.
Pros: Works with any existing upload endpoint (minimal server changes needed) and is compatible with every browser that supports XMLHttpRequest.
Cons: Adds extra load to your server, and progress updates are only as frequent as your polling interval (so it’s not real-time).
3. IFrame-Based Uploads (Legacy Approach)
Before XMLHttpRequest 2.0 existed, developers used hidden iframes to handle file uploads without page refreshes. You can hack this approach to simulate progress:
- Submit your file form to a hidden iframe.
- On the server side, as you receive the file, periodically output small chunks of JavaScript (e.g.,
parent.updateProgress(40);) that tell the parent page the current progress. - Listen for changes in the iframe’s content on the client side, execute those snippets, and update your progress bar.
Pros: Extremely backward-compatible (works even with super old browsers).
Cons: Clunky to implement, requires server-side streaming of progress updates, and feels outdated compared to modern methods.
Quick Hack for Edge 15
As a temporary fix for Edge specifically, some developers have had luck replacing xhr.send() with xhr.sendAsBinary() (a deprecated method, but Edge 15 still supports it). This can sometimes force the progress events to fire correctly during upload. That said, this is a band-aid—chunked upload is the better long-term solution.
Overall, chunked upload is the way to go here. It solves your Edge problem, improves upload reliability for large files, and gives you extra features like resumable uploads. Most modern upload libraries have chunked upload support built-in, so you might even be able to tweak your existing implementation instead of building from scratch.
内容的提问来源于stack exchange,提问作者Lukich

