반응형

[a tag]

<a href={questionModalSrc} download="88a2f203a144c233726b8ffcdccc9ed8.png">

href 주소의 Type이 이미지나 파일이어야만 다운로드가능,

  • download='img.png'에서 img.png는 변경가능
  • 확장자 안쓰면 알아서 다운로드시 Type에 해당하는 확장자 붙여줌,
  • img.htm이런식으로 확장자 잘못 붙여도 다운로드 가능

 

 <a href={`/board/viewimage?file=${encodeURIComponent(questionModalSrc)}`}>

Type이 document (html문서)라면 다운로드 에러남
href가 file Type이 아니면 이런식으로 다운로드 에러남, 이 때 img.htm의 확장자 htm은 저절로 알아서 붙은것

 

 

 

 

 

[모든 element에 적용가능한 방법] 클릭시 임시로 a tag생성하고 클릭되도록

onClick={() => { const link = document.createElement('a');  
                link.href = \`/common/files/01. CDP Admin Operation Policy.docx\`;  
                link.target = '\_blank';//링크클릭시 새창에서 열도록, 링크여는목적 아니므로 없어도 될듯  
                link.download = '다운로드될 파일명'; 이 부분이 없으면 자동다운로드 안됨
                document.body.appendChild(link);  
                link.click();  
                document.body.removeChild(link);  
              }}

 

 

 

 

 

외부에 있는 자원을 다운로드

API 구현부분

  • 테스트해보니 요청하는 헤더내의 content_type: application/json이지만 응답헤더의 Content-Type: application/octet-stream
    Content-Disposition: attachement; filename="RBSPOT.json"로 응답함
  • 참고로 다른 요청->응답은 아래와 같았음
    • 일반적인 json Fetch/XHR request -> response
      • content-type: application/json -> Content-Type: application/json;charset=UTF-8
    • 파일을 자동으로 다운로드되도록 하는 request -> response
      • content-type: application/json -> Content-Type: application/octet-stream
        Content-Disposition: attachement; filename="RBSPOT.json"
    • 파일을 서버로 업로드하는 request -> response
      • Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryCr6S7zpBWkWbkGAB ->
@Description("MetaDataFile Download from Admin.")
@GetMapping
@PreAuthorize("hasRole('ADMIN')")
@RequestMapping("/api/admin/apiCallLog/{apiCallLogId}/file")
public ResponseEntity<?> getMetaDataFile(@CurrentUser UserPrincipal currentUser,
    @PathVariable Long apiCallLogId) {

  Map<String, Object> resultMap = new HashMap<String, Object>();
  URL url = new URL(...어찌어찌해서 얻어옴);
  InputStreamResource resource = new InputStreamResource(url.openStream());
  resultMap.put("fileName", apiCallInfo.getFileName());
  resultMap.put("resource", resource);

  return ResponseEntity.ok().contentType(MediaType.parseMediaType("application/octet-stream"))
      .header(HttpHeaders.CONTENT_DISPOSITION,
          "attachement; filename=\"" + resultMap.get("fileName") + "\"")
      .body(resultMap.get("resource"));
}

구현된 API call하는 부분

export async function getFileDownload(requestPath, requestMethod, rowData) {
  await fetch(API_BASE_URL + requestPath, {
    method: 'GET',
    headers: getHeaders(),
  })
    .then(response => {
      return response.blob();
    })
    .then(blob => {
      const url = window.URL.createObjectURL(
        new Blob([blob]),
      );
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute(
        'download',
        rowData.fileName,
      );//filename to be downloaded, it can be used as link.download=fileName
      //link.style='display:none'; //OK it is not given
      document.body.appendChild(link);
      link.click();
      link.parentNode.removeChild(link);
    })
    .catch(err => {
      alert('error')
    });
}

서버 내부 자원(public공간내 file) 다운로드

<button
                  type="button"
                  className="quick_link link1"
                  onClick={() => {
                    const link = document.createElement('a');
                    link.href = `/common/files/01. CDP Admin Operation Policy_(ENG)20210428.docx`;
                    link.target = '_blank';
                    link.download = '01. CDP Admin Operation Policy_(ENG)20210428.docx';
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                  }}>

서버응답을 받아 파일을 내려주거나 내부소스 파일을 내려주거나 다운로드 하는 부분의 공통점

const link = document.createElement('a');
link.href = `/common/files/01. CDP Admin Operation Policy_(ENG)20210428.docx`;//여기에서 차이남
//link.target = '_blank'; //없어도됨
link.download = '01. CDP Admin Operation Policy_(ENG)20210428.docx'; //link.setAttribute('download', 파일명)과 동일
document.body.appendChild(link);
link.click();
document.body.removeChild(link);//link.remove(); link.parentNode.removeChild(link);와 동일

서버응답을 받아 파일생성하는 부분

new Blob([arrayContetns], options) options는 생략가능

new Blob([response], {type" res.headers[content-type]})

Blob을 URL로 변환

window.URL.createObjectURL(blob)

URL.revokeObjectURL( window.URL.createObjectURL(blob) ) 여기서 window.URL=URL인듯

반응형

+ Recent posts