본문 바로가기

프로그래밍/Javascript

[Javascript] 로컬에 파일 저장

인터넷 익스플로러IE


Blob 및 msSaveBlob를 사용하여 로컬에 파일 저장

이 항목은 웹 저장소를 사용하여 로컬에 파일 저장을 중단한 부분부터 시작하며Blob 생성자를 window.navigator.msSaveBlob 및window.navigator.msSaveOrOpenBlob 메서드와 함께 사용하여 임의의 크기의 파일을 로컬로 저장하는 방법을 보여 줍니다.

이 항목의 내용은 다음과 같습니다.

참고  다음 예에서는 Internet Explorer 10 이상이 필요합니다.
 

BlobBuilder API를 사용하여 BOLB 만들기

Blob 생성자를 사용하면 클라이언트에서 BLOB(파일과 동등)를 쉽게 만들어 직접 조작할 수 있습니다. Internet Explorer 10의 msSaveBlob 및 msSaveOrOpenBlob 메서드를 사용하면 인터넷에서 파일을 다운로드할 때처럼(다운로드한 파일이 다운로드 폴더에 자동으로 저장됨) 클라이언트에 파일을 저장할 수 있습니다.

msSaveBlob 메서드는 저장 단추만 사용자에게 제공하는 반면 msSaveOrOpenBlob 메서드는 저장 및 열기 단추를 모두 제공한다는 것이 두 메서드 간의 차이점입니다.

Blob 생성자 및 msSaveBlob/msSaveOrOpenBlob를 사용하여 클라이언트에서 변경된 파일을 저장하는 방법은 다음 예제를 참조하세요.

예제 1

<!DOCTYPE html>
<html>

<head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <title>Example 1</title>
</head>

<body>
  <h1>Example 1</h1>
  <script>
    var blobObject = new Blob(["I scream. You scream. We all scream for ice cream."]); 
    
    window.navigator.msSaveBlob(blobObject, 'msSaveBlob_testFile.txt'); // The user only has the option of clicking the Save button.
    alert('File save request made using msSaveBlob() - note the single "Save" button below.');
    
    var fileData = ["Before you insult a person, walk a mile in their shoes. That way, when you insult them, you'll be a mile away - and have their shoes."];
    blobObject = new Blob(fileData);
    window.navigator.msSaveOrOpenBlob(blobObject, 'msSaveBlobOrOpenBlob_testFile.txt'); // Now the user will have the option of clicking the Save button and the Open button.
    alert('File save request made using msSaveOrOpenBlob() - note the two "Open" and "Save" buttons below.');
  </script>
</body>

</html>


먼저 Blob()생성자를 사용하여 해당 매개 변수가 원하는 파일 콘텐츠를 포함하는 배열인 blob 개체를 만듭니다.

var blobObject = new Blob(["I scream. You scream. We all scream for ice cream."]);

그런 다음 blobObject에서 콘텐츠를 복사하여 텍스트 파일로 저장합니다(이 파일은 다운로드 폴더에 저장됨).

window.navigator.msSaveBlob(blobObject, 'msSaveBlob_testFile.txt');

참고   사용자가 알림 표시줄에서 연결된 프롬프트를 적절하게 클릭하여 권한을 제공한 경우에만 msSaveBlob_testFile.txt를 다운로드 폴더에 저장할 수 있습니다.
 

이 프로세스는 msSaveOrOpenBlob 메서드를 사용하여 반복되며, 사용자에게 저장 옵션과 열기 옵션을 모두 제공합니다.

다음 예제는 Blob 기능 검색을 추가합니다.

예제 2

<!DOCTYPE html>
<html>

<head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <title>Example 2</title>
</head>

<body>
  <h1>Example 2</h1>
  <script>
    function requiredFeaturesSupported() {
      return ( BlobConstructor() && msSaveOrOpenBlobSupported() );
    }
    
    function BlobConstructor() {
      if (!window.Blob) {
        document.getElementsByTagName('body')[0].innerHTML = "<h1>The Blob constructor is not supported - upgrade your browser and try again.</h1>";
        return false;
      } // if
      
      return true;
    } // BlobConstructor
    
    function msSaveOrOpenBlobSupported() {
      if (!window.navigator.msSaveOrOpenBlob) { // If msSaveOrOpenBlob() is supported, then so is msSaveBlob().
        document.getElementsByTagName('body')[0].innerHTML = "<h1>The msSaveOrOpenBlob API is not supported - try upgrading your version of IE to the latest version.</h1>";            
        return false;
      } // if
      
      return true;
    } // msSaveOrOpenBlobSupported
        
    if (requiredFeaturesSupported()) {
      var blobObject = new Blob(["I scream. You scream. We all scream for ice cream."]);
      
      window.navigator.msSaveBlob(blobObject, 'msSaveBlob_testFile.txt');
      alert('File save request made using msSaveBlob() - note the single "Save" button below.');
      
      var fileData = ["Before you insult a person, walk a mile in their shoes. That way, when you insult them, you'll be a mile away - and have their shoes."];
      blobObject = new Blob(fileData);
      window.navigator.msSaveOrOpenBlob(blobObject, 'msSaveBlobOrOpenBlob_testFile.txt');
      alert('File save request made using msSaveOrOpenBlob() - note the two "Open" and "Save" buttons below.');
    }
  </script>
</body>

</html>

파일을 클라이언트에 저장한 후 저장된 파일에서 데이터를 검색해야 합니다. 다음 예에서는 로컬 파일 읽기 및 웹 저장소를 사용하여 로컬에 파일 저장을 기반으로 간단한 canvas 기반 그림을 만들어 로컬 파일에 저장하고 그런 저장된 그림을 표시할 수 있습니다. 이 예제는 일반적으로 다음과 같이 사용됩니다.

  1. 마우스 또는 손가락(터치식 장치에만 해당)을 사용하여 상자 내에 그림을 만듭니다.
  2. 저장 단추를 클릭한 다음 결과 알림 표시줄에서 결과 저장 단추를 클릭합니다.
  3. x를 클릭하여 두 번째 알림 표시줄을 해제합니다.
  4. 지우기 단추를 클릭합니다.
  5. 로드 단추를 클릭하고 결과 찾아보기 단추를 클릭한 다음 이전에 저장한 그림 파일을 선택합니다. 저장된 그림이 표시됩니다.

그림을 저장한 후 4단계를 건너뛰면 사용자가 여러 그림을 합성할 수 있습니다.

예제 3

<!DOCTYPE html>
<html>

<head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <title>Example 3</title>
  <style>
    html { 
     -ms-touch-action: none; /* Capture all touch events for our own purposes. */
     text-align: center;
    }
  
    #hideWrapper { 
      display: none; /* Do not show the file picker dialog until we're ready to do so. */
    }    
  </style>
</head>

<body>
  <h1>Example 3</h1>
  <canvas id="drawingSurface" width="500" height="500" style="border:1px solid black;">
  </canvas> <!-- The canvas element can only be manipulated via JavaScript -->
  <div>
    <button id="erase">Erase</button>
    <button id="save">Save</button>
    <button id="load">Load</button>
  </div>  
  <div id="hideWrapper">
    <p>Select one of your saved canvas drawings to display:</p>
    <input type="file" id="fileSelector" /> <!-- By design, if you select the exact same files two or more times, the 'change' event will not fire. -->
  </div>    
  <script>
    function requiredFeaturesSupported() {
      return ( 
               BlobConstructorSupported() && 
               msSaveOrOpenBlobSupported() && 
               canvasSupported() && 
               fileApiSupported()
             );
    } // requiredFeaturesSupported
    
    function BlobConstructorSupported() {
      if (!window.Blob) {
        document.getElementsByTagName('body')[0].innerHTML = "<h1>The Blob constructor is not supported - upgrade your browser and try again.</h1>";
        return false;
      } // if
      
      return true;
    } // BlobConstructorSupported
    
    function msSaveOrOpenBlobSupported() {
      if (!window.navigator.msSaveOrOpenBlob) { // If msSaveOrOpenBlob() is supported, then so is msSaveBlob().
        document.getElementsByTagName('body')[0].innerHTML = "<h1>The msSaveOrOpenBlob API is not supported - upgrade Internet Explorer and try again.</h1>";            
        return false;
      }
      
      return true;
    } // msSaveOrOpenBlobSupported
        
    function canvasSupported() {
      if (!document.createElement('canvas').getContext) {
        document.getElementsByTagName('body')[0].innerHTML = "<h1>Canvas is not supported - upgrade your browser and try again.</h1>";                  
        return false;
      }
      
      return true;
    } // canvasSupported  
    
    function fileApiSupported() {
      if (document.getElementById('fileSelector').files && window.FileReader) {
        return true;        
      }
      else {
        document.getElementsByTagName('body')[0].innerHTML = "<h1>The File API is not sufficiently supported - upgrade your browser and try again.</h1>";            
        return false;      
      }
    } // fileSelectorSupported      
        
    if ( requiredFeaturesSupported() ) {    
      var canvas = document.getElementById('drawingSurface'); // A static variable, due to the fact that one or more local functions access it.
      var context = canvas.getContext('2d'); // A static variable, due to the fact that one or more local functions access it.

      context.fillStyle = "purple"; // Because purple is cool.

      if (window.navigator.msPointerEnabled) {
        canvas.addEventListener('MSPointerMove', paintCanvas, false);
      }
      else {
        canvas.addEventListener('mousemove', paintCanvas, false);
      }

      document.getElementById('erase').addEventListener('click', eraseCanvas, false);
      document.getElementById('save').addEventListener('click', saveCanvas, false);
      document.getElementById('load').addEventListener('click', loadCanvas, false);
      
      document.getElementById('fileSelector').addEventListener('change', handleFileSelection, false); // Add an onchange event listener for the <input id="fileSelector"> element.      
    } // if ( requiredFeaturesSupported() )
    
    function paintCanvas(event) { // The "event" object contains the position of the pointer/mouse.
      context.fillRect(event.offsetX, event.offsetY, 4, 4); // Draw a 4x4 rectangle at the given coordinates (relative to the canvas box). As of this writing, not all browsers support offsetX and offsetY.
    }

    function saveCanvas() {
      var drawingFileName = "canvas" + Math.round( (new Date()).getTime() / 1000 ) + ".txt"; // Produces a unique file name every second.
      var blobObject = new Blob( [canvas.toDataURL()] ); // Create a blob object containing the user's drawing.
      
      window.navigator.msSaveBlob(blobObject, drawingFileName); // Copy the blob object content and save it to a file.
      document.getElementById('hideWrapper').style.display = 'none'; // Remove the file picker dialog from the screen if the Save button gets clicked.      
    } // saveCanvas

    function eraseCanvas() {
      context.clearRect(0, 0, context.canvas.width, context.canvas.height);
      document.getElementById('hideWrapper').style.display = 'none'; // Remove the file picker dialog from the screen if the Erase button gets clicked.
    } // eraseCanvas

    function loadCanvas() {
      document.getElementById('hideWrapper').style.display = 'block'; // Unhide the file picker dialog so the user can select a saved canvas drawing to load into the canvas element.   
    } // loadCanvas      
    
    function handleFileSelection(evt) {    
      var files = evt.target.files; // The file selected by the user (as a FileList object).

      if (!files) {
        alert("The selected file is invalid - do not select a folder. Please reselect and try again.");
        return;
      }

      // "files" is a FileList of file objects. Try to display the contents of the selected file:
      var file = files[0]; // The way the <input> element is set up, the user cannot select multiple files.
      
      if (!file) {
        alert("Unable to access " + file.name.toUpperCase() + "Please reselect and try again."); 
        return;
      }
      if (file.size == 0) {
        alert("Unable to access " + file.name.toUpperCase() + " because it is empty. Please reselect and try again.");
        return;
      }
      if (!file.type.match('text/.*')) {
        alert("Unable to access " + file.name.toUpperCase() + " because it is not a known text file type. Please reselect and try again.");
        return;
      }
      
      // Assert: we have a valid file.
      
      startFileRead(file); // Asychronously fire off a file read request.      
      document.getElementById('hideWrapper').style.display = 'none'; // Remove the file picker dialog from the screen since we have a valid file.      
    } // handleFileSelection
    
    function startFileRead(fileObject) {
      var reader = new FileReader(); //

      // Set up asynchronous handlers for file-read-success, file-read-abort, and file-read-errors:
      reader.onloadend = displayDrawing; // "onloadend" fires when the file contents have been successfully loaded into memory.
      reader.abort = handleFileReadAbort; // "abort" files on abort.
      reader.onerror = handleFileReadError; // "onerror" fires if something goes awry.

      if (fileObject) { // Safety first.
        reader.readAsText(fileObject); // Asynchronously start a file read thread. Other supported read methods include readAsArrayBuffer() and readAsDataURL().
      }
      else {
        alert("fileObject is null in startFileRead().");
      }
    } // startFileRead
    
    function displayDrawing(evt) {
      var img = new Image(); // The canvas drawImage() method expects an image object.
  
      img.src = evt.target.result; // Obtain the file contents, which was read into memory (whose format is a text data URL string).
      // eraseCanvas(); To allow composite drawings, remove this comment.
      img.onload = function() { // Only render the saved drawing when the image object has fully loaded the drawing into memory.
        context.drawImage(img, 0, 0); // Draw the image starting at canvas coordinate (0, 0) - the upper left-hand corner of the canvas.
      } // img.onload */
    } // displayFileText
      
    function handleFileReadAbort(evt) {
      alert("File read aborted.");
    } // handleFileReadAbort

    function handleFileReadError(evt) {
      switch (evt.target.error.name) {
        case "NotFoundError":
          alert("The file could not be found at the time the read was processed.");
          break;
        case "SecurityError":
          alert("A file security error occured.");
          break;
        case "NotReadableError":
          alert("The file cannot be read. This can occur if the file is open in another application.");
          break;
        case "EncodingError":
          alert("The length of the data URL for the file is too long.");
          break;
        default:
          alert("File error code " + evt.target.error.name);
      } // switch
    } // handleFileReadError
  </script>
</body>

</html>

예제 3의 기능 중 하나는 동일한 그림 파일을 두 번 연속해서 다시 로드할 수 없다는 것입니다. 즉, 다음 절차는 실패합니다.

  1. 그림이 있는 경우 지우기를 클릭합니다.
  2. 마우스 또는 손가락(터치식 장치에만 해당)을 사용하여 상자 내에 그림을 만듭니다.
  3. 저장 단추를 클릭한 다음 결과 알림 표시줄에서 결과 저장 단추를 클릭합니다.
  4. x를 클릭하여 두 번째 알림 표시줄을 해제합니다.
  5. 지우기 단추를 클릭합니다.
  6. 로드 단추를 클릭한 다음 결과 찾아보기 단추를 클릭하고 3단계에서 만든 그림 파일을 선택합니다. 저장된 그림이 표시됩니다.
  7. 지우기 단추를 클릭합니다.
  8. 로드 단추를 클릭한 다음 결과 찾아보기 단추를 클릭하고 6단계에서 선택한 것과 동일한 그림 파일을 선택합니다. 그림이 표시되지 않습니다.

이 동작은 의도된 것이지만 쉽게 해결할 수 있습니다. 먼저 <input type="file" id="fileSelector" /> 요소를 <form> 요소 내에 다음과 같이 배치합니다.

<div id="hideWrapper">
  <p>Select one of your saved canvas drawings to display:</p>
  <form>
    <input type="file" id="fileSelector" />
  </form>
</div>    
<script>

그런 다음 로드 단추를 클릭할 때마다 양식의 reset() 메서드를 호출하여 양식의 자식 요소에서 이전 사용자 입력을 지웁니다.

function loadCanvas() {
  document.querySelector('#hideWrapper > form').reset(); // Allow the input element to pick the same file consecutively more than once.    
  document.getElementById('hideWrapper').style.display = 'block'; // Unhide the file picker dialog so the user can select a saved canvas drawing to load into the canvas element.   
} // loadCanvas

이 업데이트된 예제를 여기서 사용할 수 있습니다. 예제 4(웹 페이지를 마우스 오른쪽 단추로 클릭하고 소스 보기를 선택하여 소스 코드 표시).

마찬가지로 예제 5는 단순 그림 "앱"을 개선하고 canvas.toDataURL()을 canvas.msToBlob()로 바꾸어 예제 4를 확장합니다. canvas.toDataURL()을 사용하여 다른 응용 프로그램을 사용하여 저장된 그림을 쉽게 볼 수 있는 가능성을 차단합니다. 그림을 PNG 파일로 저장하면 브라우저를 비롯하여 다양한 표준 응용 프로그램에서 그림을 표시할 수 있다는 이점이 있습니다. canvas.msToBlob()으로 전환하여 다음과 같이 파일을 PNG 형식으로 직접 저장할 수 있습니다.

function saveCanvas() {
  var drawingFileName = "canvas" + Math.round( (new Date()).getTime() / 1000 ) + ".png"; // Produces a unique file name every second.
  
  window.navigator.msSaveBlob(globals.canvas.msToBlob(), drawingFileName); // Save the user's drawing to a file.
  document.getElementById('filePickerWrapper').style.display = 'none'; // Remove the file picker dialog from the screen since we just saved the user's file.
} // saveCanvas

또한 파일을 PNG 형식으로 저장하면 startFileRead(file)와 연결된 세 콜백 함수를 다음과 같은 네 줄의 코드로 바꿀 수 있습니다.

img.src = window.URL.createObjectURL(file);
img.onload = function() { 
  globals.context.drawImage(img, 0, 0); 
  window.URL.revokeObjectURL(this.src); 
}

전체 예제를 여기서 사용할 수 있습니다. 예제 5(웹 페이지를 마우스 오른쪽 단추로 클릭하고 소스 보기를 선택하여 소스 코드 표시).

결론적으로 Windows Internet Explorer의 msSaveBlob 및 msSaveOrOpenBlob 메서드를 Blob 생성자와 함께 사용하면 클라이언트에서 수정된 파일을 저장할 수 있습니다. Internet Explorer 10 이전 버전에서는 이 작업이 상대적으로 어려웠습니다.

관련 항목

Internet Explorer 10 샘플 및 자습서
파일 API
로컬 파일을 관리하는 방법
로컬 파일 읽기
웹 저장소를 사용하여 로컬에 파일 저장

 

출처 : https://msdn.microsoft.com/ko-kr/library/hh779016(v=vs.85).aspx








기타 브라우저


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/toPromise';
 
 
@Injectable()
export class EnterpriseService{
 
constructor(private http: Http) {
       
    }
 
sendDownloadRequest(url) {
        let headers = new Headers({
            'Content-Type''text/csv'
        });
        return this.http.get(url, { headers: headers })
            .toPromise()
            .then(res => {
                if(res && res["_body"]){
                    this.downloadFile(res["_body"]);
                }
            })
            .catch(this.handleError);
    }
 
handleError(error){
        console.log("error--  "+error);
}
 
downloadFile(data){
        let blob = new Blob(['\ufeff' + data], { type: 'text/csv;charset=utf-8;' });
        let dwldLink = document.createElement("a");
        let url = URL.createObjectURL(blob);
        let isSafariBrowser = navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1;
        if (isSafariBrowser) {  //if Safari open in new window to save file with random filename.
        dwldLink.setAttribute("target""_blank");
    }
        dwldLink.setAttribute("href"url);
        dwldLink.setAttribute("download""Enterprise.csv");
        dwldLink.style.visibility = "hidden";
        document.body.appendChild(dwldLink);
        dwldLink.click();
        document.body.removeChild(dwldLink);
   }
}

THANKS