javascript 下载 csv 文件作为对 AJAX 请求的响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46638343/
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-10-29 06:49:45  来源:igfitidea点击:

Download csv file as response on AJAX request

javascriptdatatables

提问by Daniel Gebrahanus

I have an endpoint called '/downloadUserAction' that collects data and downloads a csv file. The challenge I am having is that the file won't get downloaded when calling endpoint using a button on click function, however it'll download only when I access the endpoint directly in the browser.

我有一个名为“/downloadUserAction”的端点,用于收集数据并下载 csv 文件。我面临的挑战是使用单击功能上的按钮调用端点时不会下载文件,但是只有当我直接在浏览器中访问端点时它才会下载。

Upon research, I've came across findings that concluded that you cannot use AJAX to download files. That makes sense, since when I click on my button I see the endpoint being hit and the file contents being passed in the network tab, however no file gets downloaded on the client.

经过研究,我发现不能使用 AJAX 下载文件的结论。这是有道理的,因为当我点击我的按钮时,我看到端点被命中并且文件内容正在网络选项卡中传递,但是没有文件被下载到客户端。

This is all I'm simply doing on the javascript side using data tables button plug-in feature on my page to call my endpoint.

这就是我在 javascript 端所做的一切,使用页面上的数据表按钮插件功能来调用我的端点。

$(document).ready(function () {
    var table = $("#userActivity").on('init.dt', function() {
            }).DataTable({
                dom: 'Blfrtip',
                buttons: [
                          {
                            extend: 'csvHtml5',
                            text: 'NLP Search Download',
                            action: function ( e, dt, node, config ) {
                                $.ajax({
                                    url : window.location + "/downloadUserAction?draw=3&search%5Bvalue%5D=NLP_SEARCH&order%5B0%5D%5Bcolumn%5D=6&order%5B0%5D%5Bdir%5D=desc"                        
                                });
                            }
                          }
                      ],

Is there another method of calling my endpoint that will force a download on the client page?

是否有另一种调用我的端点的方法会强制在客户端页面上下载?

side-note: my data table is using server side processing otherwise I would've just used datatables csv exporting button.

旁注:我的数据表正在使用服务器端处理,否则我只会使用数据表 csv 导出按钮。

回答by Brett Zamir

In modern browsers, you can prompt a download by creating a Blob with your file contents (in your case received by Ajax), creating a URL for it, and using the downloadattribute:

在现代浏览器中,您可以通过使用您的文件内容(在您的情况下由 Ajax 接收)创建一个 Blob,为其创建一个 URL,并使用以下download属性来提示下载:

const saveData = (function () {
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, fileName) {
        const blob = new Blob([data], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

const data = 'a,b,c\n5,6,7',
    fileName = "my-csv.csv";

saveData(data, fileName);

JSFiddle

JSFiddle

If your Ajax endpoint URL has the proper headers (or possibly even if it isn't as long as you use the downloadattribute), you can forego the Blob and Ajax and just add the URL to the link with the download attribute. Adapting @pritesh's code,

如果您的 Ajax 端点 URL 具有正确的标头(或者即使它不是只要您使用该download属性的标头),您就可以放弃 Blob 和 Ajax,只需将 URL 添加到带有下载属性的链接。改编@pritesh 的代码,

const saveData = (function () {
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (url, fileName) {
        a.href = url;
        a.download = fileName;
        a.click();
    };
}());

const url = 'http://www.sample-videos.com/csv/Sample-Spreadsheet-10-rows.csv', // Replace with your own URL: window.location + "/downloadUserAction?draw=3&search%5Bvalue%5D=NLP_SEARCH&order%5B0%5D%5Bcolumn%5D=6&order%5B0%5D%5Bdir%5D=desc"
    fileName = "my-csv.csv";

saveData(url, fileName);

JSFiddle

JSFiddle

回答by pritesh

Since it gets downloaded when you access the endpoint directly from the browser so what you can do is set an anchor tag inside the button and set the href attribute of the anchor tag to the url pointing to the csv file.I have created a sample example here:

由于它是在您直接从浏览器访问端点时下载的,因此您可以做的是在按钮内设置一个锚标记并将锚标记的 href 属性设置为指向 csv 文件的 url。我创建了一个示例示例这里:

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>
    <button>
        <a href="http://www.sample-videos.com/csv/Sample-Spreadsheet-10-rows.csv">Click me</a>
    </button>
</body>
</html>

If you try out this code in browser, then onclick a dialog will appear for saving the file.

如果您在浏览器中尝试此代码,则 onclick 将出现一个用于保存文件的对话框。

In your case you need the replace the sample videos url with your own.

在您的情况下,您需要将示例视频 url 替换为您自己的。

window.location + "/downloadUserAction?draw=3&search%5Bvalue%5D=NLP_SEARCH&order%5B0%5D%5Bcolumn%5D=6&order%5B0%5D%5Bdir%5D=desc"

window.location + "/downloadUserAction?draw=3&search%5Bvalue%5D=NLP​​_SEARCH&order%5B0%5D%5Bcolumn%5D=6&order%5B0%5D%5Bdir%5D=desc"