web-dev-qa-db-ja.com

jquery ajax postを介してファイルをダウンロードする

Webページのデータをエクスポートして、Excelファイルとしてダウンロードしようとしています。しかし、応答が成功してもダウンロードは開始されません。

$.ajax({
      type: "POST",
      url: _url,
      contentType: 'multipart/form-data;boundary=SzB12x',
      data: json,
    });

ResponseTextは次のようなものです。

PK�J; Fxl/theme /theme1.xml�YOo�6�-���、[r��n;v��i����#-�kJH:�oC{0X7�2��mZ���d��u@�(٦b:M���������{|��^�0t@��* "w $�!0I�[�n�i��'����iH�g�、��|�J�! ���hRh�h��?r&�L���߶S��v@���#��׮� "���}��Жt%�hR�t''������+ ��������u{ނ��0K���oy�9OTWywkAͯ����F��6 *�����[���U���

私はそのファイルだと思うが、私はそれをダウンロードできない!

助けてください?

ありがとう!

10

私は同じ問題に直面し、正常に解決しました。私のユースケースはこれです。

  • JSONデータをサーバーに投稿し、Excelファイルを受信します。
  • そのExcelファイルはその場で作成され、クライアントへの応答として返されます。

コード:

$("#my-button").on("click", function() {
    // Data to post
    data = {
        ids: [1, 2, 3, 4, 5]
    };

    // Use XMLHttpRequest instead of Jquery $ajax
    xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        var a;
        if (xhttp.readyState === 4 && xhttp.status === 200) {
            // Trick for making downloadable link
            a = document.createElement('a');
            a.href = window.URL.createObjectURL(xhttp.response);
            // Give filename you wish to download
            a.download = "test-file.xls";
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
        }
    };
    // Post data to URL which handles post request
    xhttp.open("POST", excelDownloadUrl);
    xhttp.setRequestHeader("Content-Type", "application/json");
    // You should set responseType as blob for binary responses
    xhttp.responseType = 'blob';
    xhttp.send(JSON.stringify(data));
});

上記のスニペットは次のことをしています

  • XMLHttpRequestを使用してサーバーに配列をJSONとして投稿する
  • コンテンツをblob(binary)として取得した後、ダウンロード可能なURLを作成し、非表示の「a」リンクに添付してクリックします。

ここでは、サーバー側でいくつかの設定を慎重に行う必要があります。 Python Django= HttpResponse。他のプログラミング言語を使用している場合は、それに応じて設定する必要があります。

# In python Django code
response = HttpResponse(file_content, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")

ここでxls(Excel)をダウンロードしたので、contentTypeを上記のものに調整しました。ファイルの種類に応じて設定する必要があります。

14
Naren Yellavula

非表示のフォームを使用してリクエストを送信してみてください。

ユーザーがHTMLフォームを送信すると、ユーザーによってフォームに入力されたすべてのデータは、GETまたはPOST FORMの「ACTION」属性で指定されたURLへのリクエストとして送信されます。

 <FORM action="http://www.labnol.org/sendmail.php" method="post">
 ...form contents...
 </FORM>

上記の例では、HTTP POSTリクエストがフォーム送信時にsendmail.phpスクリプトに発行されます。target=” _ blank”をFORMタグに追加して、リクエストを新しいウィンドウで処理できます。

ただし、ブラウザを別のページにリダイレクトせずに、バックグラウンドでページのFORMを送信する場合(フォームの送信時にdocument.location.hrefが変更される)、次の2つのオプションがあります。

オプション1。 HTMLページ内に非表示のIFRAMEを作成し、それを元のFORMのターゲットとして設定できます。これにより、フォームが送信されますが、親ウィンドウはリロードされません。

<FORM action="http://example.com/script.php" 
           method="POST" target="hidden-form">
 ...form contents... 
 </FORM>
<IFRAME style="display:none" name="hidden-form"></IFRAME> 

オプション#2:フォームを送信する前にカスタムペイロードを作成できる別の方法があります。 IFRAMEベースのフォーム送信とは異なり、次のコードは標準のフォーム送信リクエストを作成するため、ブラウザーの場所が変更され、現在のページがブラウザー履歴に追加されます。クレジット:Rakesh Pai。

submitFORM('http://example.com/script.php', 'POST',
    {'name':'digital+inspiration', 'age':'100', 'sex','M'});

function submitFORM(path, params, method) {
    method = method || "post"; 

    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    //Move the submit function to another variable
    //so that it doesn't get overwritten.
    form._submit_function_ = form.submit;

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }

    document.body.appendChild(form);
    form._submit_function_();
}

this リンクでは、非表示フォームを作成する方法を見つけることができますそれを提出してください。

楽しい!!

5
mohammad

ここでのアプローチは、 https://Gist.github.com/DavidMah/3533415 から直接解除されます。

このアプローチでは<form>およびデータにキーを追加します。このアプローチは、サーバーがリクエスト本体そのものではなく、リクエスト本体の属性としてデータをすでに期待している場合に機能します。アップロードするデータがオブジェクトの場合、そのオブジェクトのキーを反復処理できます。アップロードするデータが配列の場合、サーバールートを変更するか、[ここにアイデアを追加]のいずれかを実行します。

ブラウザで

// Takes a URL, param name, and data string
// Sends to the server... The server can respond with binary data to download
jQuery.download = function(url, key, data) {
    // Build a form
    var form = $('<form></form>').attr('action', url).attr('method', 'post');
    // Add the one key/value
    form.append($("<input></input>").attr('type', 'hidden').attr('name', key).attr('value', data));
    //send request
    form.appendTo('body').submit().remove();
};

サーバー上

# A Tidbit of sinatra code to respond
# Assume 'url' is a set variable
# Assume 'key' is the key of the value used in the javascript

post url do
  data = params[:key]
  puts request.body.read
  headers['Content-Type'] = "application/octet-stream"

  body(data)
end

$.download('/path/resource/', 'data', JSON.stringify(data))
2
prototype

ファイルをダウンロードするだけであれば、ajaxを使用してダウンロードする必要はありません。実際、ajaxを使用してファイルをダウンロードすることはできません。
ハイパーリンクを作成することにより、引き続き実行できます<a href="your_link">Export</a>応答するサーバーページへのリクエストcontent-typeapplication/vnd.ms-Excelおよびcontent-dispositionattachmentです。

1
Cà phê đen