如何在 web2py 下载失败时在视图中显示 flash 错误消息?

How to show flash error message in view when download is failed in web2py?

我有自定义下载功能。当用户点击下载图标时,首先文件被解密然后下载。此下载图标出现在加载组件中。

解密成功,返回文件。如果解密失败,我想显示 'Download failed'.

的闪现消息

这是我的自定义下载函数:

def custom_download():      
    download_row = db(db.documents.id == request.args(0)).select().first()
    download_file = download_row.file

    # Name of file is table_name.field.XXXXX.ext, so retrieve original file name
    org_file_name = db.documents.file.retrieve(download_file)[0]
    file_header = "attachment; filename=" + org_file_name

    response.headers['ContentType'] = "application/octet-stream"
    response.headers['Content-Disposition'] = file_header

    file_full_path = os.path.join(request.folder, 'uploads', download_file)
    decrypted_file = decrypt_file(file_full_path)

    if decrypted_file:
        fh = open(decrypted_file, 'rb')
        return response.stream(fh)
    else:
        return "Download Failed"

如何在控制器视图中触发闪现消息?或者任何其他方式告诉用户下载失败。

我能想到的完成此操作的最简单方法是对文件执行 ajax 请求,如果结果为 'Download Failed',则更改 DOM 以显示页面某处容器中的错误消息。您也可以让操作生成一个 HTTP 错误代码,这样您就不必解析返回的数据。

有你要的例子:Download a file by jQuery.Ajax

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

问题是如果下载 link 是常规 link(即不触发 Ajax 请求),那么如果您 return 文件以外的东西。或者,如果您使 link 触发 Ajax 请求,您将无法 return 文件。因此,一种方法是在解密失败的情况下重定向回原始页面:

    if decrypted_file:
        fh = open(decrypted_file, 'rb')
        return response.stream(fh)
    else:
        session.flash = 'Download failed'
        redirect(URL('original_controller', 'original_function', extension=False))
使用

session.flash 因为有重定向。另外,请注意 extension=False 确保当前请求的扩展名不会传播到重定向 URL(默认情况下,URL() 帮助程序传播当前请求的扩展名)。

唯一的缺点是在失败的情况下,必须完全重新加载父页面,但假设失败相对较少,这应该影响很小。

另一种方法是创建一个函数来生成解密的文件和 return 一条 success/failure 消息,以及第二个函数来提供文件。您将向第一个函数发出 Ajax 请求,并根据结果显示失败消息或将 window.location 设置为第二个函数的 URL 以下载文件。在成功下载的情况下,第一种方法更简单且效率更高(只有一个请求而不是两个)。