我有一个页面,用户单击按钮即可下载文件。它应该解密文件,下载文件,然后删除解密的文件。间歇性发生的情况是在下载完成之前发生删除。有时文件被部分下载,有时根本没有下载。
我通常会在服务器端下载文件,但由于这是一个 AJAX 页面,因此我使用的方法似乎不起作用。因此,我在服务器和客户端之间来回做了一些事情。
这是单击按钮后触发的 VB.NET 服务器端子程序:
Sub DownloadFile()
output = MapPath + _hdnFilePath.Value
input = output.Replace("_dec", "_enc")
crptFile.Decrypt(input, output)
Dim encodedFileName As String = _hdnFilePath.Value.Replace("'", "@@@")
RadAjaxManager1.ResponseScripts.Add("downloadURI('" & encodedFileName & "');")
''OLD DOWNLOAD METHOD BELOW - does not work with ajax
'Response.Clear()
'Response.ContentType = "application/pdf"
'Response.AppendHeader("Content-Disposition", "attachment; filename=" +
'Path.GetFileName(output))
'Response.WriteFile(output)
'Response.Flush()
'Delete the decrypted (output) file.
'File.Delete(output)
End Sub
这是此函数触发的 JavaScript:
function downloadURI(encodedFileName) {
encodedFileName = encodedFileName.replace(/\@\@\@/g, "'");
var encodedURI = encodeURIComponent(encodedFileName)
encodedFileName = encodedFileName.replace("###", "%").replace("$$$", "&")
fetch('<%= ResolveUrl("/CUTracking/CUFiles/") %>' + encodedURI)
.then(resp => resp.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = encodedFileName;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
a.remove();
})
.catch(() => alert('There was an error'));
$find("<%= RadAjaxManager1.ClientID %>").ajaxRequest("Delete")
}
这是由 javascript 下载功能触发的删除 VB.NET 子程序:
Protected Sub RadAjaxManager1_AjaxRequest(sender As Object, e As
AjaxRequestEventArgs)
If e.Argument = "Delete" Then
File.Delete(MapPath + _hdnFilePath.Value)
End If
End Sub
有什么办法可以防止文件被过早删除,或者有没有一种不那么迂回的方法来解决这个问题?我仅使用 blob 来尝试解决此问题,并且仅使用 javascript 来下载文件,因为我的服务器端方法不适用于 AJAX。
此建议无法解决您面临的同步问题,但您的下载脚本还有改进的空间。
当您创建临时元素(在本例中为锚点)时,无需将其附加到文档中...
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none'; // <-- You don't need this
a.href = url;
a.download = encodedFileName;
document.body.appendChild(a); // <-- You don't need this
a.click();
window.URL.revokeObjectURL(url);
a.remove(); // <-- You don't need this
此外,下载应在新窗口中打开,从而生成此版本...
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.target = '_blank'; // <-- new window
a.href = url;
a.download = encodedFileName;
a.click();
window.URL.revokeObjectURL(url);
我更改的另一件事是将 const 声明更改为 vars。
常量应该用于永远不会改变的数据,例如一周中的几天或一年中的月份,如下所示:
const DaysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];