带有自定义标题的AJAX文件下载

我想发送请求到URL,它提供了我文件下载对话框。 同时,服务器需要请求头中的某些参数。 所以我想在请求中插入自定义标头并获取响应文件。 有什么方法可以实现这个目标吗?

谢谢,阿米特

尝试使用data-*设置为header for request a元素, $.ajax()并将headers选项设置为元素data-headers对象。

$.ajax() successa元素href设置为在objectURL作为Blob响应, download属性downloadfile.name或临时文件名,在元素上调用.click()以激活“保存文件”对话框。

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

据我所知,您想要从Web请求一个需要身份validation标题但无法通过简单链接下载的文件。

您需要做的是使用身份validation标头进行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") ) }) 

它还使用es6中提供的一些新的suger语法,可以使用babel或traceur转换为es5

如果您不包含fetch polyfill并需要支持旧浏览器 – 那么您需要使用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") } 

也许我不明白你的观点。

我认为是这样的:

 //server xxx.php //omit some code echo 'file_name'; //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); } }) 

好的,我查了一个旧的应用程序,这里有一个样本。 你需要适应,但这个想法就在这里。 第一部分是放置在WebMethod上的Request拦截器属性的一部分。 整个拦截器非常复杂,因为它管理了几个案例。

 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的第二部分。 我们使用ExtJS而不是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; } 

单击一个按钮将调用此函数并为其提供WebMethod的URL,并最终传递额外的args。 JS方面的想法是创建一个隐藏的iFrame,它将获取URL,然后提示用户下载。

我希望它有所帮助