2012-10-24 2 views
1

이 문제가 있습니다. 이 요청은 기본 파일을 판독하는 서블릿에 의해 처리된다파일 다운로드 Extjs4 with Ajax 요청

Ext.Ajax.request({ 
url: 'DownloadServlet', 
method: 'GET',  
}); 

: 합성에서 난을 클릭하면 이와 같은 Ajax 요청을 수행하는 다운로드 버튼을 갖는다. 파일 읽기가 성공적입니다. 실제로는 방화 광에서 GET 상태가 "200"입니다.

문제는 프런트 엔드 (extjs)가 파일을 다운로드하는 것을 관리하지 않는 것입니다. 나는 브라우저가 파일을 다운로드하기 위해 고전적인 더 많은 창을 보여줄 것으로 기대한다.

무엇이 될 수 있습니까? 감사합니다

답변

1

AJAX 전화로 파일을 다운로드 할 수 없습니다. 기본적으로 하드와 단순의 2 가지 솔루션이 있습니다.

간단 : 파일이 저장된 url에서 리디렉션하기 위해 window.popup 또는 document.location.href를 사용하면 정상적인 브라우저 다운로드 방법을 사용할 수 있습니다. 그냥 당신이

하드 응용 프로그램/octet-stream을 같이 브라우저가 렌더링되지 않습니다 마임을 보내는해야합니다 : 당신이 AJAX 호출 이진 또는 Base64로 인코딩 된 파일의 콘텐츠를하고 HREF를 base64 인코딩와 다운로드 링크를 만들 수 있습니다. Chrome에서는 다음과 같이 표시됩니다.

<a href="base64,mime-type,...encoded trash..." download="download"> 

다른 브라우저에 대한 해결책이 있지만 현재는 Chrome에서만 이상적입니다. 다른 브라우저의 나는 그 같은 코드를 사용하고 있습니다 :

var showSave; 

// Feature test: Does this browser support the download attribute on anchor tags? (currently only Chrome) 
var DownloadAttributeSupport = 'download' in document.createElement('a'); 

// Use any available BlobBuilder/URL implementation: 
var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; 
var URL = window.URL || window.webkitURL || window.mozURL || window.msURL; 

// IE 10 has a handy navigator.msSaveBlob method. Maybe other browsers will emulate that interface? 
// See: http://msdn.microsoft.com/en-us/library/windows/apps/hh441122.aspx 
navigator.saveBlob = navigator.saveBlob || navigator.msSaveBlob || navigator.mozSaveBlob || navigator.webkitSaveBlob; 

// Anyway, HMTL5 defines a very similar but more powerful window.saveAs function: 
// http://www.w3.org/TR/file-writer-api/#the-filesaver-interface 
window.saveAs = window.saveAs || window.webkitSaveAs || window.mozSaveAs || window.msSaveAs; 
// However, this is not supported by any browser yet. But there is a compatibility library that 
// adds this function to browsers that support Blobs (except Internet Exlorer): 
// http://eligrey.com/blog/post/saving-generated-files-on-the-client-side 
// https://github.com/eligrey/FileSaver.js 

// mime types that (potentially) don't trigger a download when opened in a browser: 
var BrowserSupportedMimeTypes = { 
    "image/jpeg": true, 
    "image/png": true, 
    "image/gif": true, 
    "image/svg+xml": true, 
    "image/bmp": true, 
    "image/x-windows-bmp": true, 
    "image/webp": true, 
    "audio/wav": true, 
    "audio/mpeg": true, 
    "audio/webm": true, 
    "audio/ogg": true, 
    "video/mpeg": true, 
    "video/webm": true, 
    "video/ogg": true, 
    "text/plain": true, 
    "text/html": true, 
    "text/xml": true, 
    "application/xhtml+xml": true, 
    "application/json": true 
}; 

// Blobs and saveAs (or saveBlob) : 
if (BlobBuilder && (window.saveAs || navigator.saveBlob)) { 
    // Currently only IE 10 supports this, but I hope other browsers will also implement the saveAs/saveBlob method eventually. 
    showSave = function (data, name, mimeType) { 
     var builder = new BlobBuilder(); 
     builder.append(data); 
     var blob = builder.getBlob(mimetype||"application/octet-stream"); 
     if (!name) name = "Download.bin"; 
     // I don't assign saveAs to navigator.saveBlob (or the other way around) 
     // because I cannot know at this point whether future implementations 
     // require these methods to be called with 'this' assigned to window (or 
     // naviagator) in order to work. E.g. console.log won't work when not called 
     // with this === console. 
     if (window.saveAs) { 
      window.saveAs(blob, name); 
     } 
     else { 
      navigator.saveBlob(blob, name); 
     } 
    }; 
} 
else if (window.Blob && URL && window.atob) { 
    // atob to base64_decode the data-URI 
    showSave = function (data, name, mimetype) { 
     var image_data = atob(data); 
     // Use typed arrays to convert the binary data to a Blob 
     var arraybuffer = new ArrayBuffer(image_data.length); 
     var view = new Uint8Array(arraybuffer); 
     for (var i=0; i<image_data.length; i++) { 
      view[i] = image_data.charCodeAt(i) & 0xff; 
     } 
     var blob = new Blob([arraybuffer], {type: 'application/octet-stream'}); 

     // Use the URL object to create a temporary URL 
     var url = URL.createObjectURL(blob); 
     //window.open(url, '_blank', ''); 
     document.location.href = url 
    } 
} 
// Blobs and object URLs: 
else if (BlobBuilder && URL) { 
    // Currently WebKit and Gecko support BlobBuilder and object URLs. 
    showSave = function (data, name, mimetype) { 
     var blob, url, builder = new BlobBuilder(); 
     builder.append(data); 
     if (!mimetype) mimetype = "application/octet-stream"; 
     if (DownloadAttributeSupport) { 
      blob = builder.getBlob(mimetype); 
      url = URL.createObjectURL(blob); 
      // Currently only Chrome (since 14-dot-something) supports the download attribute for anchor elements. 
      var link = document.createElement("a"); 
      link.setAttribute("href",url); 
      link.setAttribute("download",name||"Download.bin"); 
      // Now I need to simulate a click on the link. 
      // IE 10 has the better msSaveBlob method and older IE versions do not support the BlobBuilder interface 
      // and object URLs, so we don't need the MS way to build an event object here. 
      var event = document.createEvent('MouseEvents'); 
      event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null); 
      link.dispatchEvent(event); 
     } 
     else { 
      // In other browsers I open a new window with the object URL. 
      // In order to trigger a download I have to use the generic binary data mime type 
      // "application/octet-stream" for mime types that browsers would display otherwise. 
      // Of course the browser won't show a nice file name here. 
      if (BrowserSupportedMimeTypes[mimetype.split(";")[0]] === true) { 
       mimetype = "application/octet-stream"; 
      } 

      blob = builder.getBlob(mimetype); 
      url = URL.createObjectURL(blob); 
      //window.open(url, '_blank', ''); 
      document.location.href = url 
     } 
     // The timeout is probably not necessary, but just in case that some browser handle the click/window.open 
     // asynchronously I don't revoke the object URL immediately. 
     setTimeout(function() { 
      URL.revokeObjectURL(url); 
     }, 250); 

     // Using the filesystem API (http://www.w3.org/TR/file-system-api/) you could do something very similar. 
     // However, I think this is only supported by Chrome right now and it is much more complicated than this 
     // solution. And chrome supports the download attribute anyway. 
    }; 
} 
// data:-URLs: 
else if (!/\bMSIE\b/.test(navigator.userAgent)) { 
    // IE does not support URLs longer than 2048 characters (actually bytes), so it is useless for data:-URLs. 
    // Also it seems not to support window.open in combination with data:-URLs at all. 
    showSave = function (data, name, mimetype) { 
     if (!mimetype) mimetype = "application/octet-stream"; 
     // Again I need to filter the mime type so a download is forced. 
     if (BrowserSupportedMimeTypes[mimetype.split(";")[0]] === true) { 
      mimetype = "application/octet-stream"; 
     } 
     // Note that encodeURIComponent produces UTF-8 encoded text. The mime type should contain 
     // the charset=UTF-8 parameter. In case you don't want the data to be encoded as UTF-8 
     // you could use escape(data) instead. 
     window.open("data:"+mimetype+";base64,"+data, '_blank', ''); 
    }; 
} 
// Internet Explorer before version 10 does not support any of the methods above. 
// If it is text data you could show it in an textarea and tell the user to copy it into a text file. 

업데이트 : https://github.com/dcneiner/Downloadify

3

을보십시오 : Flash를 사용하는 것이 확인되어 , 여기가 아닌 크롬 브라우저에 대한 대체 솔루션입니다
downloadWhatever : function() { 
    Ext.core.DomHelper.append(document.body, { 
      tag : 'iframe', 
      id : 'downloadIframe', 
      frameBorder : 0, 
      width : 0, 
      height : 0, 
      css : 'display:none;visibility:hidden;height:0px;', 
      src : '/your/restful/url/' 
     }); 
    }, 

서버 측 스프링

@RequestMapping(value = "/url", method = RequestMethod.GET) 
public void download(HttpServletRequest request, 
     HttpServletResponse response) throws ServletRequestBindingException, IOException { 
    String tempFile = .. get your file 
    File file = new File(tempFile); 
      // in case you have zipped it ... 
      // else set the correct ContentType 
    response.setContentType("application/zip"); 
    response.setContentLength((int) file.length()); 
    response.setHeader("fileName", file.getName()); 
    response.setHeader("Content-Disposition", "attachment; filename="+ file.getName()); 

    InputStream in = new FileInputStream(file); 
    OutputStream out = response.getOutputStream(); 
    byte[] buffer = new byte[1024]; 
    int read = 0; 
    while ((read = in.read(buffer, 0, buffer.length)) != -1) { 
     out.write(buffer, 0, read); 
    } 

    in.close(); 
    out.flush(); 
    out.close(); 
} 
(경우에 당신이 궁금해)