Je souhaite envoyer une requête à une URL qui me fournit une boîte de dialogue de téléchargement de fichier. Dans le même temps, le serveur a besoin de certains paramètres dans l'en-tête de requête. Je souhaite donc insérer un en-tête personnalisé dans la requête et obtenir un fichier en réponse. Y a-t-il une façon d'y parvenir?
Merci, Amit
Essayez d'utiliser a
élément avec des data-*
réglé sur les en-têtes pour la demande, $.ajax()
avec l'option des en- headers
configurée sur a
élément d'en data-headers
élément.
À $.ajax()
success
défini a
élément href
pour répondre en tant que Blob
dans objectURL
, download
attribut dans le nom du fichier ou du fichier temporaire, appeler .click()
sur a
élément pour activer la boîte de dialogue "Enregistrer le fichier".
$(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>
D'après ce que je comprends, vous souhaitez demander un fichier sur le Web qui nécessite un en-tête d'authentification mais ne peut pas être téléchargé avec un lien simple.
Ce que vous devez faire, c'est faire un appel ajax avec l'en-tête d'authentification pour télécharger les données en tant que blob. Ensuite, enregistrez les données du côté client
Les méthodes ajax / get de jQuery ne sont pas compatibles avec responseType = blob
Donc, cet exemple utilise la dernière Fetch API dans Blink et Firefox. Il utilise également FileSaver.js pour sauvegarder un blob généré côté client en fonction des manières de gérer les problèmes de navigation croisée.
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") ) })
Il utilise également une nouvelle syntaxe suger qui est disponible dans es6 qui peut être transpilée à es5 avec babel ou traceur
Si vous n'incluez pas un polyfill de récupération et que vous devez prendre en charge les anciens navigateurs – Ensuite, vous devez le faire de l'ancien mode avec 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") }
Peut-être que je ne comprends pas votre point de vue.
Ce que je pense est comme ceci:
//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); } })
Ok, j'ai vérifié une ancienne application que j'avais et voici un exemple. Vous devrez vous adapter mais l'idée est ici. Cette première partie fait partie d'un attribut Request interceptor qui est placé sur le WebMethod
. Tout l'intercepteur est assez complexe car il gère plusieurs cas.
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();
C'est la deuxième partie du Javascript du côté client. Nous avons utilisé ExtJS au lieu de 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; }
Le clic d'un bouton appellerait cette fonction et lui donnerait l'URL du WebMethod et éventuellement des args supplémentaires à passer. L'idée sur le côté JS est de créer un iFrame caché qui prendrait l'URL et lui demanderait alors de télécharger.
J'espère que ça contribue