2012-11-27 13 views
14

Chcę wysłać żądanie do adresu URL, który zawiera okno dialogowe pobierania pliku. W tym samym czasie serwer potrzebuje pewnych parametrów w nagłówku żądania. Dlatego chcę wstawić niestandardowy nagłówek do żądania i uzyskać plik w odpowiedzi. Czy jest jakiś sposób, żeby to osiągnąć?Pobieranie pliku AJAX z niestandardowym nagłówkiem

Dzięki Amit

+1

Jakiego rodzaju informacje dodajesz do nagłówka żądania? Odnosząc się do odpowiedzi, po prostu odeślij to, czego chcesz, używając czegoś w stylu 'Response.Clear(); Response.ContentType = "application/text"; Response.ContentEncoding = _ex.Encoding; Response.AddHeader ("content-disposition", String.Format ("attachment; filename = {0}", _ex.FileName)); Response.BinaryWrite (_ex.Output); Response.End(); ' –

+0

[This] (http://stackoverflow.com/questions/24501358/how-to-set-a-header-for-a-http-get-request-and-trigger-file -download/24523253 # 24523253) nie jest dokładnie duplikatem pytania, ale jest przeznaczone specjalnie dla żądań GET, ale odpowiedzi tam mogą być przydatne. –

Odpowiedz

-1

Może ja nie rozumiem twój punkt widzenia.

Co moim zdaniem jest tak:

//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); 
    } 
}) 
+2

Myślę, że dużym problemem jest nagłówek żądania. Jak dostosować je w wywołaniu ajax. –

+0

Myślę, że możemy nie ustawić nagłówków żądań i upewnić się, że nagłówek odpowiedzi zawiera treść - załącznik: załącznik. Ale na pytanie o pobieranie pliku ajax, nie wiem, dlaczego w ten sposób. Możemy bezpośrednio pobierać pliki i nie odświeża strony. Z drugiej strony, XMLHttpRequest nie może uzyskać danych binarnych –

+0

@ Rex Huang, jesteś w błędzie. xhr może uzyskać dane binarne ... po prostu ustaw 'arachiber' xhr.responseType = ' – Endless

-1

Ok, sprawdziłem w starej aplikacji miałem i oto próbka. Musisz się dostosować, ale pomysł jest tutaj. Ta pierwsza część jest częścią atrybutu przechwytywacza żądań, który jest umieszczony na WebMethod. Cały przechwytujący jest dość złożony, ponieważ zarządza kilkoma przypadkami.

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(); 

To jest druga część w JavaScript po stronie klienta. Użyliśmy ExtJS zamiast jQuery.

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; 
} 

Kliknięcie przycisku wywoływałoby tę funkcję i podawało jej adres WebMethod, a ostatecznie dodatkowe argumenty do przekazania. Ideą strony JS jest utworzenie ukrytej ramki iFrame, która pobierze adres URL, a następnie wyświetli monit o pobranie.

Mam nadzieję, że pomaga się

8

Spróbuj użyć a elementu z data-* zestaw do nagłówków na żądanie, $.ajax() z headers opcja jest ustawiona na a elementu data-headers obiektu.

Na $.ajax()success ustawić a elementu href do odpowiedzi jako Blob ciągu objectURL, download atrybut file.name lub tymczasową nazwą pliku, zadzwoń .click() na a elementu, aby uaktywnić okno „Zapisz plik”.

$(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>

6

Z tego co rozumiem, jest to, że chcesz poprosić o plik z sieci, które wymagają uwierzytelniania nagłówek ale nie można pobrać za pomocą prostego łącza.

Co należy zrobić, to wykonać wywołanie ajax z nagłówkiem uwierzytelniania, aby pobrać dane jako blob. Następnie należy zapisać dane ze strony klienta


ajax jQuery/get metody nie robi wspierających responseType = blob

Więc ten przykład jest z wykorzystaniem najnowszych Fetch API w Blink i Firefox. Używa także FileSaver.js do zapisywania kropli generowanej po stronie klienta w porównaniu do sposobów radzenia sobie z problemami z przeglądarką.

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") 
     ) 
    }) 

również korzystać z niektórych nowych suger składni, która jest dostępna w ES6 które można transpiled do ES5 z babel lub Traceur

Jeśli nie obejmują fetch polyfill i potrzebę wspierania starszych przeglądarek - wtedy trzeba to zrobić w starym stylu z 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") 
}