使用 Ajax 从 Servlet 下载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3502267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:54:29  来源:igfitidea点击:

Download a file from Servlet using Ajax

ajaxservletsdownloadsave-as

提问by Vinay

I have created a zip file in my servlet. Now I would like to trigger that servlet using Ajax and prompt the download dialog to the user. I can trigger the servlet, but I don't know how to get the save dialog. How can I achieve this?

我在我的 servlet 中创建了一个 zip 文件。现在我想使用 Ajax 触发该 servlet 并向用户提示下载对话框。我可以触发 servlet,但我不知道如何获取保存对话框。我怎样才能做到这一点?

回答by RoToRa

You can't "download a file using AJAX". AJAX is about downloading data from a server for JavaScript to process.

您不能“使用 AJAX 下载文件”。AJAX 是关于从服务器下载数据以供 JavaScript 处理。

To let the user download the file either use a simple link to the file/servlet, or if you really, really need to use JavaScript, then assign the URL to document.location.href.

要让用户下载文件,请使用指向文件/servlet 的简单链接,或者如果您确实需要使用 JavaScript,则将 URL 分配给document.location.href.

Also you need to make sure that the server (or in this case the servlet) sends the appropriate MIME type, in case of a ZIP file most likely application/zip.

此外,您还需要确保服务器(或在这种情况下是 servlet)发送适当的 MIME 类型,以防最有可能是 ZIP 文件application/zip

回答by BalusC

You can't use Ajax for this. You basically want to let the enduser save the file content to the local disk file system, not to assign the file content to a JavaScript variable where it can't do anything with it. JavaScript has for obvious security reasons no facilities to programmatically trigger the Save Asdialog whereby the file content is provided from an arbitrary JavaScript variable.

您不能为此使用 Ajax。您基本上希望让最终用户将文件内容保存到本地磁盘文件系统,而不是将文件内容分配给 JavaScript 变量,因为它无法对其进行任何操作。出于明显的安全原因,JavaScript 没有以编程方式触发另存为对话框的工具,其中文件内容是从任意 JavaScript 变量提供的。

Just have a plain vanilla link point to the servlet URL and let the servlet set the HTTP Content-Dispositionheader to attachment. It's specifically this header which will force the browser to pop a Save Asdialog. The underlying page will stay same and not get refreshed or so, achieving the same experience as with Ajax.

只需有一个指向 servlet URL 的普通链接,然后让 servlet 将 HTTPContent-Disposition标头设置为attachment. 特别是这个标题将强制浏览器弹出另存为对话框。底层页面将保持不变,不会刷新左右,实现与 Ajax 相同的体验。

Basically:

基本上:

<a href="fileservlet/somefilename.zip">download file</a>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // ...

    response.setHeader("Content-Type", getServletContext().getMimeType(fileName));
    response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");

    // ...
}

That could also be done in JavaScript as below without firing a whole Ajax call:

这也可以在 JavaScript 中完成,如下所示,而无需触发整个 Ajax 调用:

window.location = "fileservlet/somefilename.zip";

Alternatively, if you're actually using POST for this, then use a (hidden) synchronous POST form referring the servlet's URL and let JavaScript perform a form.submit()on it.

或者,如果您实际上为此使用 POST,则使用(隐藏的)同步 POST 表单引用 servlet 的 URL,并让 JavaScript 对其执行 a form.submit()

See also:

也可以看看:

回答by Master Mind

function down() {

    var url = "/Jad";
    var xmlhttp;

    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        //alert("xmlhttp.status" + xmlhttp.status);
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {

        }

    }


    xmlhttp.open("GET", url, true);
    xmlhttp.send();


    var elemIF = document.createElement("iframe");
    elemIF.src = url;
    elemIF.style.display = "none";
    document.body.appendChild(elemIF);
}