Keywords: File Download Detection | Cookie Token | JavaScript Polling | Browser Extension API | Client-Server Collaboration
Abstract: This article explores solutions for detecting browser file download completion in web applications. Addressing the challenge of lengthy dynamic file generation, it presents a client-server collaborative detection mechanism based on cookie tokens. Through steps including unique token generation, waiting indicator setup, and periodic cookie status polling, accurate file download completion detection is achieved. The article provides detailed analysis of traditional method limitations and offers complete JavaScript and PHP implementation code, while discussing browser extension API as a supplementary approach.
Problem Background and Challenges
In modern web applications, dynamically generating files and providing downloads is a common requirement. However, when file generation processes are time-consuming, users need clear feedback about operation status. Traditional methods attempt to detect download completion by listening to iframe load events, but face numerous limitations in practical applications.
Key challenges include: browser behavior differences when handling Content-Disposition: attachment headers, and compatibility issues with multipart/x-mixed-replace responses across different browsers. Firefox correctly processes multipart responses and triggers load events, while Internet Explorer and Safari exhibit different behavioral patterns.
Core Solution: Cookie Token Mechanism
The cookie token mechanism based on client-server collaboration provides a reliable solution. The core concept involves generating a unique token on the client side, having the server set corresponding cookies when files are ready, and the client polling cookie status to determine download completion.
Client Implementation Details
Client-side JavaScript code handles token generation, waiting indicator state management, and periodic polling of server-set cookies. Key functions include:
function getCookie(name) {
var parts = document.cookie.split(name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
function setFormToken() {
var downloadToken = new Date().getTime();
document.getElementById("downloadToken").value = downloadToken;
return downloadToken;
}
function blockResubmit() {
var downloadToken = setFormToken();
setCursor("wait", "wait");
downloadTimer = window.setInterval(function() {
var token = getCookie("downloadToken");
if ((token == downloadToken) || (attempts == 0)) {
unblockSubmit();
}
attempts--;
}, 1000);
}
Server-Side Processing Logic
The server needs to receive tokens passed from the client and set corresponding cookies when files are ready for download. PHP implementation example:
public function setCookieToken($cookieName, $cookieValue, $httpOnly = true, $secure = false) {
setcookie(
$cookieName,
$cookieValue,
2147483647,
"/",
$_SERVER["HTTP_HOST"],
$secure,
$httpOnly
);
}
$TOKEN = "downloadToken";
$this->setCookieToken($TOKEN, $_GET[$TOKEN], false);
$result = $this->sendFile();
Browser Extension API as Supplementary Approach
Beyond cookie-based solutions, modern browser extension APIs provide alternative methods for detecting download events. Through the downloads API, developers can monitor download initiation, status changes, and completion events.
Browser extension manifest.json configuration example:
{
"name": "my-extension",
"version": "1.0.4",
"permissions": ["downloads"],
"manifest_version": 2,
"background": {
"scripts": ["app.js"]
}
}
Extension background script monitoring download events:
function handleCreated(downloadItem) {
console.log(`Download from ${downloadItem.url} at starttime ${downloadItem.startTime}`);
}
browser.downloads.onCreated.addListener(handleCreated);
Implementation Considerations and Best Practices
During actual deployment, multiple technical details require consideration: token uniqueness guarantee, cookie security settings, polling frequency optimization, and cross-browser compatibility handling. Recommended best practices include:
Using high-precision timestamps or UUIDs as tokens to ensure uniqueness; setting appropriate cookie expiration times to avoid long-term browser storage occupation; adjusting polling frequency based on application scenarios to balance real-time performance and overhead; providing fallback solutions to maintain basic functionality during network anomalies or cookie disablement.
Performance Optimization and Error Handling
Performance optimization and robustness design require attention during solution implementation. By limiting polling attempts (such as 30 attempts in the example), promptly clearing timers and cookie resources, memory leaks can be avoided. Simultaneously, implement comprehensive error handling mechanisms, including proper handling of network timeouts, server errors, and user download cancellations.
For large-scale concurrent scenarios, consider using WebSocket or Server-Sent Events as alternatives to polling mechanisms, providing more real-time status updates. However, implementation complexity and browser compatibility requirements must be balanced.