인터넷 익스플로러IE
Blob 및 msSaveBlob를 사용하여 로컬에 파일 저장
이 항목은 웹 저장소를 사용하여 로컬에 파일 저장을 중단한 부분부터 시작하며Blob 생성자를 window.navigator.msSaveBlob
및window.navigator.msSaveOrOpenBlob
메서드와 함께 사용하여 임의의 크기의 파일을 로컬로 저장하는 방법을 보여 줍니다.
이 항목의 내용은 다음과 같습니다.
BlobBuilder API를 사용하여 BOLB 만들기
Blob 생성자를 사용하면 클라이언트에서 BLOB(파일과 동등)를 쉽게 만들어 직접 조작할 수 있습니다. Internet Explorer 10의 msSaveBlob 및 msSaveOrOpenBlob 메서드를 사용하면 인터넷에서 파일을 다운로드할 때처럼(다운로드한 파일이 다운로드 폴더에 자동으로 저장됨) 클라이언트에 파일을 저장할 수 있습니다.
msSaveBlob
메서드는 저장 단추만 사용자에게 제공하는 반면 msSaveOrOpenBlob
메서드는 저장 및 열기 단추를 모두 제공한다는 것이 두 메서드 간의 차이점입니다.
Blob 생성자 및 msSaveBlob
/msSaveOrOpenBlob
를 사용하여 클라이언트에서 변경된 파일을 저장하는 방법은 다음 예제를 참조하세요.
<!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 기능 검색을 추가합니다.
<!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 기반 그림을 만들어 로컬 파일에 저장하고 그런 저장된 그림을 표시할 수 있습니다. 이 예제는 일반적으로 다음과 같이 사용됩니다.
- 마우스 또는 손가락(터치식 장치에만 해당)을 사용하여 상자 내에 그림을 만듭니다.
- 저장 단추를 클릭한 다음 결과 알림 표시줄에서 결과 저장 단추를 클릭합니다.
- x를 클릭하여 두 번째 알림 표시줄을 해제합니다.
- 지우기 단추를 클릭합니다.
- 로드 단추를 클릭하고 결과 찾아보기 단추를 클릭한 다음 이전에 저장한 그림 파일을 선택합니다. 저장된 그림이 표시됩니다.
그림을 저장한 후 4단계를 건너뛰면 사용자가 여러 그림을 합성할 수 있습니다.
<!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의 기능 중 하나는 동일한 그림 파일을 두 번 연속해서 다시 로드할 수 없다는 것입니다. 즉, 다음 절차는 실패합니다.
- 그림이 있는 경우 지우기를 클릭합니다.
- 마우스 또는 손가락(터치식 장치에만 해당)을 사용하여 상자 내에 그림을 만듭니다.
- 저장 단추를 클릭한 다음 결과 알림 표시줄에서 결과 저장 단추를 클릭합니다.
- x를 클릭하여 두 번째 알림 표시줄을 해제합니다.
- 지우기 단추를 클릭합니다.
- 로드 단추를 클릭한 다음 결과 찾아보기 단추를 클릭하고 3단계에서 만든 그림 파일을 선택합니다. 저장된 그림이 표시됩니다.
- 지우기 단추를 클릭합니다.
- 로드 단추를 클릭한 다음 결과 찾아보기 단추를 클릭하고 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 이전 버전에서는 이 작업이 상대적으로 어려웠습니다.
관련 항목
출처 : https://msdn.microsoft.com/ko-kr/library/hh779016(v=vs.85).aspx
기타 브라우저