1 |
|
2 | export const BunnyFile = {
|
3 |
|
4 | /**
|
5 | * Download file from URL via AJAX and make Blob object or return base64 string if 2nd argument is false
|
6 | * Only files from CORS-enabled domains can be downloaded or AJAX will get security error
|
7 | *
|
8 | * @param {String} URL
|
9 | * @param {Boolean} convert_to_blob = true
|
10 | * @returns {Promise}: success(Blob object | base64 string), fail(response XHR object)
|
11 | */
|
12 | download(URL, convert_to_blob = true) {
|
13 | var request = new XMLHttpRequest();
|
14 | const p = new Promise( (success, fail) => {
|
15 | request.onload = () => {
|
16 | if (request.status === 200) {
|
17 | const blob = request.response;
|
18 | success(blob);
|
19 | } else {
|
20 | fail(request);
|
21 | }
|
22 | };
|
23 | });
|
24 |
|
25 | request.open('GET', URL, true);
|
26 | if (convert_to_blob) {
|
27 | request.responseType = 'blob';
|
28 | }
|
29 | request.send();
|
30 |
|
31 | return p;
|
32 | },
|
33 |
|
34 | /**
|
35 | * Get File/Blob header (signature) to parse for MIME-type or any magic numbers
|
36 | * @param {File|Blob} blob
|
37 | * @returns {Promise} callback(str:signature)
|
38 | */
|
39 | getSignature(blob) {
|
40 | return new Promise(callback => {
|
41 | const reader = new FileReader();
|
42 | reader.onloadend = () => {
|
43 | const arr = (new Uint8Array(reader.result)).subarray(0, 4);
|
44 | let signature = '';
|
45 | for (let i = 0; i < arr.length; i++) {
|
46 | signature += arr[i].toString(16);
|
47 | }
|
48 | callback(signature);
|
49 | };
|
50 | reader.readAsArrayBuffer(blob);
|
51 | });
|
52 | },
|
53 |
|
54 | /**
|
55 | * Check if string is a valid signature for image/jpeg
|
56 | * @param {String} signature
|
57 | * @returns {boolean}
|
58 | */
|
59 | isJpeg(signature) {
|
60 | const signatures = ['ffd8ffe0', 'ffd8ffe1', 'ffd8ffe2'];
|
61 | return signatures.indexOf(signature) > -1;
|
62 | },
|
63 |
|
64 | /**
|
65 | * Check if string is a valid signature for image/png
|
66 | * @param {String} signature
|
67 | * @returns {boolean}
|
68 | */
|
69 | isPng(signature) {
|
70 | return signature === '89504e47';
|
71 | },
|
72 |
|
73 | /**
|
74 | * Convert base64 string to Blob object
|
75 | * @param {String} base64
|
76 | * @returns {Blob}
|
77 | */
|
78 | base64ToBlob(base64) {
|
79 | // convert base64 to raw binary data held in a string
|
80 | // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
|
81 | var byteString = atob(base64.split(',')[1]);
|
82 |
|
83 | // separate out the mime component
|
84 | var mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
|
85 |
|
86 | // write the bytes of the string to an ArrayBuffer
|
87 | var ab = new ArrayBuffer(byteString.length);
|
88 | var ia = new Uint8Array(ab);
|
89 | for (var i = 0; i < byteString.length; i++) {
|
90 | ia[i] = byteString.charCodeAt(i);
|
91 | }
|
92 |
|
93 | // write the ArrayBuffer to a blob, and you're done
|
94 | return new Blob([ab], {type: mimeString});
|
95 | },
|
96 |
|
97 | /**
|
98 | * Convert Blob object to base64string
|
99 | * @param {Blob} blob
|
100 | * @returns {Promise} success(base64 string), fail(error)
|
101 | */
|
102 | blobToBase64(blob) {
|
103 | const reader = new FileReader;
|
104 | const p = new Promise( (success, fail) => {
|
105 | reader.onloadend = () => {
|
106 | let base64 = reader.result;
|
107 | success(base64);
|
108 | };
|
109 | reader.onerror = (e) => {
|
110 | fail(e);
|
111 | }
|
112 | });
|
113 |
|
114 | reader.readAsDataURL(blob);
|
115 |
|
116 | return p;
|
117 | },
|
118 |
|
119 | /**
|
120 | * Get local browser object URL which can be used in img.src for example
|
121 | * @param {Blob} blob
|
122 | * @returns {String}
|
123 | */
|
124 | getBlobLocalURL(blob) {
|
125 | if (!(blob instanceof Blob || blob instanceof File)) {
|
126 | throw new TypeError('Argument in BunnyFile.getBlobLocalURL() is not a Blob or File object');
|
127 | }
|
128 | return URL.createObjectURL(blob);
|
129 | }
|
130 |
|
131 | };
|