마크쓰리
804
2018-09-11 10:15:05
2
750

파일 다운로드시 다른이름으로 저장 창이 뜨지 않습니다.


보통 파일 다운로드 버튼을 클릭하면 '다른 이름으로 저장'창이 표시되는데요.

다운로드 버튼을 클릭하면 "다른 이름으로 저장"이 표시되지 않고 바로 다운로드가 됩니다.

response.setContentType에 application/octet-stream으로 되어있는걸 x-download와 zip으로 바꿔봤는데,  '다른 이름으로 저장'이 열리지 않네요..

어디서 문제가 있는걸까요.?


아래는 소스입니다.

html

 <button type="button" class="btn btn-large btn-danger" ng-click="serverInfoDownload()">Download</button>


controller.js

$scope.serverInfoDownload = function(){

        	fileDownload.downloadFile(function (success){

        		console.log("download success");

        	}, function(error){

        		console.log("error", error);

        	});

        	$(".serverInfoDownload").modal('hide');

        }


service.js

angular.module('oggApp')

    .factory('fileDownload', ['$resource', function ($resource) {

        return $resource('/api/download/',{

        	

        }, {

        	downloadFile: {

        		url: '/api/download/download',

        		method: 'GET'

        		}

        	}

        );

    }]);


controller.java


   

 @RequestMapping(value="download", method=RequestMethod.GET)

    public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {

        

    	try {

    		backup.backupDatabase();

    	} catch (SQLException e) {

    		System.out.println(e.getMessage());

    	}

    	

    	String fileName = backup.getFileName();

        File downloadfile = new File(backup.getUrl() + fileName+".zip");

        

        if (downloadfile.exists() && downloadfile.isFile()) {

            response.setContentType("application/octet-stream; charset=utf-8");

            response.setContentLength((int) downloadfile.length());

            ServletOutputStream os = null;

            FileInputStream fis = null;

            try {

                response.setHeader("Content-Disposition", getDisposition(fileName+".zip", check_browser(request)));

                response.setHeader("Content-Transfer-Encoding", "binary");

                os = response.getOutputStream();

                fis = new FileInputStream(downloadfile);



                FileCopyUtils.copy(fis, os);



            } catch (Exception e) {

                e.printStackTrace();

            } finally {

                try {

                    if (fis != null){

                    	fis.close();

                    }

                    os.flush();

                    os.close();  

                } catch (Exception e2) {}

            }

        }else {

            System.out.println("FILE Not Found");

        }

    }



     private String getDisposition(String down_filename, String browser_check) throws UnsupportedEncodingException {

        String prefix = "attachment; filename=";

        String encodedfilename = null;

        System.out.println("browser_check:"+browser_check);

        if (browser_check.equals("ie")) {

            encodedfilename = URLEncoder.encode(down_filename, "UTF-8").replaceAll("\\+", "%20");

        }else if (browser_check.equals("chrome")) {

            StringBuffer sb = new StringBuffer();

            for (int i = 0; i < down_filename.length(); i++){

                char c = down_filename.charAt(i);

                if (c > '~') {

                    sb.append(URLEncoder.encode("" + c, "UTF-8"));

                } else {

                    sb.append(c);

                }

            }

            encodedfilename = sb.toString();

        }else {

            encodedfilename = "\"" + new String(down_filename.getBytes("UTF-8"), "8859_1") + "\"";

        }

        return prefix + encodedfilename;

    }



어디서 잘못되어있는건지.. 다른 방법이 있는건지 도와주시면 감사하겠습니다..

0
0
  • 답변 2

  • guyv
    1k
    2018-09-11 11:45:15

    https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types

    이 글을 한번 읽어보시구요.


    다운로드 시 "다른 이름으로 저장"을 강제하기 위해서는 Content-Type 을

    application/octet-stream

    으로 주는게 일반적입니다.


    서버에서 보내준 Content-Type 에 따라 웹브라우저에서 "재량으로" 처리하게되겠구요.


    https://stackoverflow.com/questions/20508788/do-i-need-content-type-application-octet-stream-for-file-download


    여기도 참고하세요.


    다운로드 창이 안뜨면 로그를 보세요. 500 오류인지, 200 OK인지.

    0
  • 마크쓰리
    804
    2018-09-11 12:40:48

    guyv

    답변감사합니다.

    알려주신 링크 두개는 전부 다 읽어보았구요.

    크롬 및 익스 개발자도구 확인해보면 200 ok 정상적으로 작동합니다.

    content-type은 application/octet-stream도 해보고 zip, x-download , download 전부 다 해보았습니다.

    근데 다운로드 창이 안뜨고 바로 다운로드가 되버려가지구요.

    어디선가 잘못해준건지, 뭔가를 더 해줘야 하는지 모르겠어서 질문남겼습니다.


    답글 달면서 문득 든 생각인데요.

    다운로드 버튼을 누르면 프로젝트 내부 폴더에 db파일을 백업한 zip파일이 생기고, 이 파일을 원하는 위치에 다운로드 시키고자 하는건데, 이런 플로우는 '다른이름으로 저장'이 안뜨는 상황과 상관이 없을까요?


    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.