使用 Ajax 从 Servlet 下载文件

发布于 2024-09-14 08:22:44 字数 111 浏览 9 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

明媚如初 2024-09-21 08:22:44

您无法“使用 AJAX 下载文件”。 AJAX 是从服务器下载数据供 JavaScript 进行处理。

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

此外,您还需要确保服务器(或在本例中为 servlet)发送适当的 MIME 类型,如果 ZIP 文件很可能是 application/zip

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

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.

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.

梦里的微风 2024-09-21 08:22:44

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

只需有一个指向 servlet URL 的普通链接,并让 servlet 将 HTTP Content-Disposition 标头设置为 attachment。具体来说,这个标头将强制浏览器弹出“另存为”对话框。底层页面将保持不变并且不会刷新,从而实现与 Ajax 相同的体验。

基本上:

<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 + "\"");

    // ...
}

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

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

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

另请参阅:

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 As dialog whereby the file content is provided from an arbitrary JavaScript variable.

Just have a plain vanilla link point to the servlet URL and let the servlet set the HTTP Content-Disposition header to attachment. It's specifically this header which will force the browser to pop a Save As dialog. The underlying page will stay same and not get refreshed or so, achieving the same experience as with 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:

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.

See also:

南薇 2024-09-21 08:22:44
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);
}
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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文