当用户点击一个允许其下载文件的超链接时,我希望能将其重定向到另一个网页。然而,由于他们需要在打开/保存文件对话框中进行选择,所以在用户接受下载前,我不想将其重定向。
如何检测用户是否执行了此操作?
当用户点击一个允许其下载文件的超链接时,我希望能将其重定向到另一个网页。然而,由于他们需要在打开/保存文件对话框中进行选择,所以在用户接受下载前,我不想将其重定向。
如何检测用户是否执行了此操作?
据我多年维护download.js的经验,从JavaScript(或一般情况下也如此)无法确定用户选择下载对话框后要执行的操作。虽然这是一个常见的功能请求,但我可以自信地说这是不可能的。如果有人可以演示出机械化的方法来确定任何文件后续动作,我将愉快地支付比这个赏金高10倍的费用。
此外,问题并不仅仅在于JS规则,浏览器下载和提示文件的方式也使问题更加复杂。这意味着即使服务器也不能总是知道发生了什么。可能有一些特定情况的解决方法,但它们并不美观或简单。
你可以强制用户使用<input type=file>
重新上传已下载的文件进行验证,但这很繁琐,而且本地文件浏览对某些用户可能会产生警惕。这是确保下载的唯一可靠方法,但对于非敏感应用程序,它非常严格,并且在一些缺少文件支持的“移动”平台上无法使用。
你还可以在服务器端尝试监视并推送消息到客户端,告诉客户端文件被服务器访问了。但是,下载在打开/保存对话框出现时就开始下载,尽管在后台不可见。这就是为什么如果你等待一会儿才“接受”大文件,它看起来似乎很快下载完毕。从服务器的角度来看,无论用户做什么,活动都是相同的。
对于一个巨大的文件,你可能可以检测到整个文件未被传输,这意味着用户点击了“取消”,但这是一个复杂的同步过程,需要使用套接字、PHP消息传递、EventSource等进行大量定制编程,而收益却很小。它还存在时间竞赛的问题,而且时间长度也不确定;减慢下载速度并不利于用户满意度。
如果文件很小,它将在用户查看对话框之前进行物理下载,因此服务器将变得无用。还要考虑到一些下载管理扩展会接管该任务,它们不能保证与原始浏览器的行为相同。强制等待可能对那些需要“永远”才能“完成”下载的慢硬盘用户而言是危险的;我们都经历过这种情况,当“旋转”停下来时无法继续操作,这肯定会降低用户满意度。a[download]
下载文件。它使用service worker来模拟服务器使用content-disposition附件头处理下载的方式,将内容流式传输到磁盘上。evt.respondWith(
new Response(
new ReadableStream({...})
)
)
writer.desiredSize
。它是它愿意接收多少数据的相关性。当您向流写入内容时,它会降低所需大小(无论是计数还是字节策略)。如果它永远不增加,则表示用户可能已暂停下载。当它下降到0以下时,您正在写入比用户要求的更多数据。writer.getWriter().write(uint8).then(() => {
// Chunk have been sent to the destination bucket
// and desiredSize increase again
})
当桶未满时,该承诺将被解决。但这并不意味着块已经写入磁盘,它只意味着块已从一个流传递到另一个流(从写入 -> 可读取 -> 响应),通常会在流的开头和另一个更早的块被写入磁盘时这样做。
如果所有数据都可以适合桶(内存)中,则写入流甚至可以在用户作出选择之前完成
调整桶大小小于数据大小可能有所帮助
因此,您可以对以下内容进行假设
请注意,如果没有可转移流支持,则种子示例不会显示正确的大小,但如果您在服务工作者中完成所有操作(而不是在主线程中完成),则可以解决此问题。
检测流何时结束就像这样简单
readableStream.pipeTo(fileStream).then(done)
未来参考WICG/native-file-system可能会让您访问磁盘并写入文件,但在继续之前必须解决提示对话框承诺,这可能正是用户要求的。
最近我涉足了一个项目,需要我指定用户是否可以上传特定类型的文件,例如(用户可以上传png但不能上传pdf)。
也许我没有使用最有效的方法,但最终我做的是编写了一个小型内置“Web应用程序”,作为上传或下载的文件浏览器。
我想最接近的例子,而不泄露我的“秘密项目”,可能是https://encodable.com/filechucker/。
也许你可以编写一个简单的集成文件浏览器,就像云服务有时使用的那样(例如Dropbox),并具有检测带有自定义框和其他内容的输入的一些功能。
这只是一些想法。
window.showSaveFilePicker 是文件系统访问 API 中的函数,可以满足你的需求。但不幸的是,目前只有 Chrome 和 Edge 支持它。它返回一个 Promise--如果用户选择下载文件,则 Promise 将被解析;如果他们取消,则会引发 AbortError
。
jquery.fileDownload 允许您做到这一点:
$(document).on("click", "a.fileDownloadPromise", function () {
$.fileDownload($(this).prop('href'))
.done(function () { alert('File download a success!'); })
.fail(function () { alert('File download failed!'); });
return false;
});
请看Github:
试试这个:
<html>
<head>
<script type="text/javascript">
function Confirmation(pg) {
var res = confirm("Do you want to download?");
if(res){
window.open(pg,"_blank");
}
return res;
}
</script>
</head>
<body>
<a href="http://yoursite/download.zip" onclick="return Confirmation('http://yoursite/redirect.html');">download</a>
</body>
</html>