17

ファイルのダウンロード ダイアログ ボックスを提供する URL にリクエストを送信したいと考えています。同時に、サーバーは要求ヘッダーに特定のパラメーターを必要とします。リクエストにカスタム ヘッダーを挿入し、応答としてファイルを取得したいと考えています。これを達成する方法はありますか?

4

4 に答える 4

8

request の headers に設定し、オプションをelement objectに設定してaelement を使用してみてください。data-*$.ajax()headersadata-headers

エレメントを応答に設定$.ajax() successする際に、属性を一時ファイル名に指定し、エレメントを呼び出して「ファイルの保存」ダイアログをアクティブにします。ahrefBlobobjectURLdownloadfile.name.click()a

$(document).ready(function() {
  $("input[type=button]").click(function() {
    // set `data-headers` object
    var el = $("[data-headers]");
    el.data("headers")["x-custom-headers"] = $("input[type=text]")[0].value 
      || el.data("headers")["x-custom-headers"];
    $.ajax({
      url: URL.createObjectURL(new Blob([$("textarea").val()], {
        type: "text/plain"
      })),
      type: "GET",
      // set `headers` to `a` element `data-headers` object
      headers: $("[data-headers]").data("headers"),
      beforeSend: function(jqxhr) {
        console.log(this.headers);
        alert("custom headers" + JSON.stringify(this.headers));
      },
      success: function(data, textStatus, jqxhr) {
        var file = new Blob([data], {
          "type": jqxhr.getResponseHeader("Content-Type")
        });
        console.log(data, file);
        $("textarea, input[type=text]").val("");
        $("a")
          .attr({
            "href": URL.createObjectURL(file),
            "download": file.name || "file-" + $.now()
          }).on("click", function() {
            $(this).remove()
          })
          .get(0).click();
      },
      error: function(jqxhr, textStatus, errorThrown) {
        console.log(textStatus, errorThrown)
      }
    });
  })
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<textarea maxlength="5" placeholder="echo"></textarea>
<br>
<!-- set `x-custom-header` to `input type="text"` value -->
<input type="text" maxlength="5" placeholder="set request header" />
<br />
<input type="button" value="download" />
<!-- set default `x-custom-header` to "123" -->
<a data-headers='{"x-custom-headers":"123"}'></a>

于 2015-11-13T06:56:32.397 に答える
6

私が理解していることは、認証ヘッダーを必要とするが、単純なリンクではダウンロードできないファイルを Web から要求したいということです。

次に行う必要があるのは、認証ヘッダーを使用して ajax 呼び出しを行い、データを BLOB としてダウンロードすることです。次に、クライアント側からデータを保存します


jQuery の ajax/get メソッドは responseType = blob をサポートしていません

この例では、Blink と Firefox で最新のFetch APIを使用しています。また、FileSaver.jsを使用して、クライアント側で生成された BLOB を保存し、クロス ブラウザーの問題を処理します。

fetch("/", {headers: {"X-mashape-key": "XXXXXX-4-YYYYYY"}})
    .then( response => {
        // we can get the filename if the
        // response headers contains Content-Disposition
        var cd = response.headers.get("Content-Disposition");
        var name = cd && cd.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1];

        response.blob().then( 
            blob => window.saveAs(blob, name || "index.html")
        )
    })

また、babel または traceur を使用して es5 にトランスパイルできる es6 で利用可能な新しい suger 構文も使用します。

フェッチ ポリフィルを含めず、古いブラウザをサポートする必要がある場合 - XHR で昔ながらの方法でそれを行う必要があります。

var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.open("get", "/");
xhr.setRequestHeader("X-mashape-key", "XXXXXX-4-YYYYYY");
xhr.send();
xhr.onload = function(){
    var cd = xhr.getResponseHeader("Content-Disposition")
    var name = cd && cd.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1];

    window.saveAs(xhr.response, name || "index.html")
}
于 2015-11-17T21:34:00.093 に答える
-1

わかりました、私が持っていた古いアプリケーションをチェックインしました。これがサンプルです。適応する必要がありますが、アイデアはここにあります。この最初の部分は、 に配置される Request インターセプタ属性の一部ですWebMethod。いくつかのケースを管理するため、インターセプター全体は非常に複雑です。

int byteSize = 262144;
byte[] data = new byte[byteSize];

if (!String.IsNullOrEmpty(myfileName))
{
    _context.Response.AddHeader("Content-disposition", "attachment; filename=\"" + myfileName+ "\"");
}

_context.Response.ContentType = DefaultContentType;
_context.Response.Cache.SetCacheability(HttpCacheability.Private);
_context.Response.Cache.SetExpires(DateTime.UtcNow.AddHours(1));
_context.Response.Buffer = false;
_context.Response.BufferOutput = false;
_context.Response.AddHeader("Content-length", myStreamSize.ToString());

try
{
    int counter = 0;
    int bytesRead = mystream.Read(data, 0, byteSize);
    while ((long)counter < myStreamSize|| bytesRead > 0)
    {
        counter += bytesRead;
        if (bytesRead < byteSize)
        {
            byte[] outBuf = new byte[bytesRead];
            Array.Copy(data, outBuf, bytesRead);
            _context.Response.BinaryWrite(outBuf);
        }
        else
        {
            _context.Response.BinaryWrite(data);
        }
        bytesRead = mystream.Read(data, 0, byteSize);
    }
}
finally
{
    mystream.Close();
    mystream.Dispose();
}
_context.Response.End();

これは、クライアント側の Javascript の 2 番目の部分です。jQuery の代わりに ExtJS を使用しました。

downloadFile: function(url, getArgs) {
    if( !this.iframe )
    {
        this.iframe = document.createElement("iframe");
        this.iframe.className = "x-hidden";
        document.body.appendChild(this.iframe);
    }

    var args = Ext.urlEncode(getArgs);
    url = url + (args ? ("?" + args) : "");
    this.iframe.src = url;
}

ボタンをクリックすると、この関数が呼び出され、WebMethod への URL が渡され、最終的に追加の引数が渡されます。JS 側のアイデアは、URL を受け取り、ユーザーにダウンロードを促す非表示の iFrame を作成することです。

それが役立つことを願っています

于 2012-11-27T13:16:08.580 に答える
-1

多分私はあなたの主張を理解していません。

私が思うのは次のようなものです:

//server xxx.php
//omit some code
echo '<a href="file_path" id="download">file_name</a>';

//browser
ajax({
    url: 'http://xxxx/xxx.php',
    success: function(html){
        //append to dom and TODO other manipulations
        $(dom).append(html);
        $('#download').trigger('click');
        $(dom).remove(html);
    }
})
于 2012-11-27T10:13:53.580 に答える