ãŸããã

<input type = file />ã¹ã¿ã€ã«ã§ã®ã¹ã¿ã€ãªã³ã°ã®é£ããã«ã€ããŠã¯ããã§ã«å€ãã®ããšãèšãããŠããŸãããããã«ã€ããŠã¯ãããšãã°ãªã³ã¯1ã2ã3ã3ã4ã5ã6ãã§èªãããšãã§ããŸãã
ãã ãããã¡ã€ã«ã®ã¢ããããŒãããã»ã¹èªäœã¯ç°¡åãªããšã§ã¯ãªããããŸããŸãªæ¹æ³ããããŸãããåäžã®çæ³çãªæ¹æ³ã§ã¯ãããŸããã
ç§ã¯ã 6ãæåã«ãããžã§ã¯ãFilesãMail.Ru silverlight-loaderã®å®è£ ã«ã€ããŠãã§ã«æžããŠããŸãã åœæãiframeãflashãsilverlightãããã³éåžžã®ãã¡ã€ã«ã®ã¢ããããŒãããµããŒããããŠããŸããã ããããé²æ©ã¯ãŸã æ¢ãŸã£ãŠããããä»ã§ã¯ãã¹ãŠã®ææã®ãã©ãŠã¶ãŒã®ææ°ã®ããŒã¿çãhtml5 FileAPIãå®å šã«ãµããŒãããŠããŸãïŒå ¬å¹³ã«ã¯ãéåžžã®ããã«ãç¬ç¹ãªæ¹æ³ã§ããã€ãã®ãµããŒãããããŸãããããã«ã€ããŠã¯ä»¥äžã§è©³ãã説æããŸãïŒã
èšäºã®å·çäžã«ãChrome 9ã¯å®å®ããŠãããšå®£èšããã ããŒãžã§ã³8ã®ã€ã³ã¹ããŒã«ã®75ïŒ ã§æ¢ã«åŒ·å¶çã«æŽæ°ãããŸãã ã ãã®ãããæåã®å®å®ãããã©ãŠã¶hoorayã§File APIã®ãµããŒããç¥ããŸãïŒ
ãã®ãããªæè¡ã䜿çšããªããšããŠãŒã¶ãŒãŠãŒã¶ãŒã«å¯Ÿããç¯çœªã«ãªããšèããŸããã
èã-æ¢åã®ãªãã·ã§ã³ã«å ããŠå®è£ ãããhtml5ããŠã³ããŒãã
ãã®çµæããŠãŒã¶ãŒã«ã¯å€ãã®ã¡ãªããããããŸããã
-æ¥ç¶ãåæãããåŸã®ééçãªãªããŒãïŒããã³ãã©ãŠã¶ã®åèµ·åãïŒïŒ;
-ããŠã³ããŒããã¥ãŒã
-ããã°ã¬ã¹ããŒïŒMacOSãšSafariã®ãŠãŒã¶ãŒã¯ãå€åœã®ãã©ã°ã€ã³ãªãã§æçµçã«é²è¡ç¶æ³ã確èªã§ããŸãïŒãæ°ãå€ãã£ãå Žåã«ãã¥ãŒãããã¡ã€ã«ãåé€ããæ©èœã
File APIã䜿çšãããšãjavascriptã³ãŒãããããã°ã©ã ã§æ¬¡ã®ããšãã§ããŸãã
1.ãã€ã¢ãã°ã§éžæããããã¡ã€ã«ããµã€ãºãããã³MIMEã¿ã€ãã®ãªã¹ããååŸããŸãïŒãšããã§ããã©ãŠã¶ã¯æ¡åŒµåã«ãã£ãŠäººæ°ã®ãããã¡ã€ã«ã¿ã€ãã決å®ããªãããããããã¯ã«ãŠã³ããããã¹ãã§ã¯ãããŸããïŒã
2.ãã¡ã€ã«ã®ã³ã³ãã³ãå šäœãã¡ã¢ãªã«ããŒãããã«ããã¡ã€ã«ããå¿ èŠãªãã€ãç¯å²ãååŸããŸãïŒFlashãFirefox 3ãšã¯ç°ãªã-泚1ãåç §ïŒã
3.ãã¡ã€ã«å šäœãšãã®ã¹ã©ã€ã¹ã®äž¡æ¹ããµãŒããŒã«ã¢ããããŒãããŸãã
4.ãã¡ã€ã«ã1ã€ã®ãã©ãã°ã¢ã³ãããããã«ã¢ããããŒãããŸãã
5.è€æ°ã®ãã¡ã€ã«ãåæã«ïŒäžŠè¡ããŠïŒããŠã³ããŒãããŸãã
ã€ãŸã ãã¡ã€ã«æäœã«ãã©ã°ã€ã³ã¯å¿ èŠãããŸãããããã¯ç¢ºãã«ãšãŠãã¯ãŒã«ã§ãïŒ
ãããã
å®éããã¡ã€ã«ã®èªã¿èŸŒã¿ã¯ã»ãã®æ°è¡ã§File APIã«å®è£ ãããŠããŸãããããã€ãã®çŽ æŽãããæ©èœïŒèªã¿èŸŒã¿ãã¥ãŒãæ¥ç¶ãåæããããšãã®åèªã¿èŸŒã¿ïŒãè¿œå ããã³ãŒãã¯å°ãè€éã«ãªããŸããã
ãããžã§ã¯ãFiles Mail.Ruã®ããŒããŒã³ãŒãã¯ã¢ã¯ã»ã¹å¯èœã§é£èªåãããŠããªããã調æ»ã§ããŸããããããžã§ã¯ããšãã®æ©èœã«é¢é£ä»ããããŠããã®ã§ã 軜éããŒãã£ã³ã°ãããžã§ã¯ããäŸãšããŠäœ¿çšããŠããã®ããŒãã£ã³ã°ã¡ã«ããºã ãçŽç²ãªåœ¢ã§æ€èšããŸãã
ããã§ã¯è¡ããŸããã...
onchangeãã³ãã©ã®å ¥åã§ãã³ã°ããŸãã
oself.file_elm.onchange = function() { oself.onSelect(this); // 'this' is a DOM object here }
å ¥åãªããžã§ã¯ãã¯html5ã®è€æ°ã®å±æ§ããµããŒããããã€ã¢ãã°ã§äžåºŠã«è€æ°ã®ãã¡ã€ã«ãéžæããŠåãå ¥ããŸã ïŒæ³š2ãåç §ïŒãæå®ããMIMEã¿ã€ãã«åŸã£ãŠãã€ã¢ãã°å ã®ãã¡ã€ã«ããã£ã«ã¿ãŒããŸãã
onSelectã¡ãœããã§ã¯ãfilesé åïŒéžæãããã¡ã€ã«ã®ãã©ãŠã¶ãŒçæãªã¹ããå«ãïŒã調ã¹ãããã©ã«ãã®ããããã£ãèšå®ããåãã¡ã€ã«ã«å¯ŸããŠonSelectã€ãã³ããçæããŸãã
ãã®åŸããã¿ã³ãåäœæããŸãã å ¥åãåé€ããŠå床äœæããŠãã ããã ããã¯ããã¿ã³ããã©ãŒã å ã«ããå Žåã«ãã©ãŒã ããµãŒããŒã«éä¿¡ãããšãã«ãéžæãããã¡ã€ã«ã®åèªã¿èŸŒã¿ãé²ãããã«è¡ãããŸãã
ãã®å Žåã®ããŠã³ããŒãã®ã€ãã·ãšãŒã¿ãŒã¯ãããŒããŒãªããžã§ã¯ãenqueueUploadã®ã¡ãœãããåŒã³åºãonSelectã€ãã³ããªã¹ããŒã§ãã
/* n - , file - File idx - cnt - */ function onSelect(n, file, idx, cnt) { if(file.size > 1 * 1024 * 1024) { alert("File is too big!\nMaximum size is 1 MB."); return; } var d = document.createElement('div'); d.id = 'file_' + file.id + '_' + n; document.getElementById('file_list_' + n).appendChild(d); d.innerHTML = '<a href="#" id="file_' + file.id + '_cancel_' + n + '">X</a>' + file.name + ' (' + file.size + ') <span id="file_' + file.id + '_status_' + n + '">...</span>' document.getElementById('file_' + file.id + '_cancel_' + n).onclick = function() { window['up' + n].cancelUpload(file.id); return false; }; window['up' + n].enqueueUpload(file, 'http://lwu.no-ip.org/upload', "arg1=val1&arg2=val2"); }
enqueueUploadã¡ãœããã¯ããã¡ã€ã«ãããŒããŒã®å éšãã¥ãŒã«è¿œå ãããã¡ã€ã«ãããã³ããšã³ããã¥ãŒã«è¿œå ããŸãïŒããã³ããšã³ãã¯ãŠãŒã¶ãŒãšå¯Ÿè©±ãããŠãŒã¶ãŒããã¡ã€ã«ãã€ãŸãå ¥åãFlashãSilverlightãã©ã°ã€ã³ã®ãããããéžæã§ãããšã³ãã£ãã£ã§ãïŒãstartNextUploadã¡ãœãããåŒã³åºããŸãããã®ãã¡ã€ã«ã®ããŠã³ããŒããéå§ããããåæåäžã«æå®ããããã¡ã€ã«ã®æ°ããã§ã«åæã«ããŒããããŠããå Žåã¯å»¶æããŸãã
ãã¡ã€ã«ãããã³ããšã³ããã¥ãŒã«è¿œå ãããšãhtml5ããã³ããšã³ãã¯ããã¡ã€ã«ã®äžæã®ããã·ã¥ã®èšç®ã¡ã«ããºã ãéå§ãã[ããã·ã¥]ãåããŒãããŸãã 詳现ã«ã€ããŠã¯ãsilverlight-loaderã«é¢ããèšäºãã芧ãã ãã ã
ã¯ãã Adler32ã¢ã«ãŽãªãºã ã䜿çšããŠããã·ã¥ãå床èšç®ãããŸãã
oself.addFile = function(fo) { upFE_html5.superclass.addFile.apply(oself, [fo]); oself.calcChunkSize(fo); oself.calcFileHash(); // run calculation for next file };
ããã·ã¥ãèšç®ãããåŸãããŒã«ã«ãªããžããªã«ã¢ã¯ã»ã¹ããŠããã®ãã¡ã€ã«ã®åå倱æããããŠã³ããŒãã«é¢ããæ å ±ããããã©ããã確èªããŸãã æ å ±ãèŠã€ãã£ãå Žåãurlãã¡ã€ã«ã®å±æ§ãsessionIDããã³uploadRangeã¯ããŒã«ã«ã¹ãã¬ãŒãžããã®æ å ±ã§äžæžããããŸãã
ããŒã«ã«ã¹ãã¬ãŒãžïŒå¥åWebStorage ïŒã¯ãã»ãã·ã§ã³ã®æéïŒ SessionStorage ïŒãŸãã¯æ°žç¶çïŒ LocalStorage ïŒã®ããããã§ããŠãŒã¶ãŒåŽã«ããŒãšå€ã®åœ¢åŒã§ä»»æã®ããŒã¿ãä¿åã§ããå¥ã®html5èŠçŽ ã§ãã
ãã¥ãŒããã¡ã€ã«ã®ããŠã³ããŒãã«éãããšãstartUploadããŒãããŒããŒã¡ãœãããåŒã³åºãããonStartã€ãã³ããçºçããŠããŠã³ããŒããéå§ãããŸãã
oself.startUpload = function(id, url, data) { var fo = oself.getFile(id); fo.url = url; // at this moment url already fetched from localStorage if info presents fo.data = data; fo.full_url = fo.url + (fo.url.match(/\?/) ? '&' : '?') + fo.data; fo.retry = oself.opts.maxChunkRetries; oself.broadcast('onStart', fo); oself.uploadFile(fo); };
uploadFileã¡ãœããã¯ããã¡ã€ã«ããµãŒããŒã«çŽæ¥ã¢ããããŒãããŸãã
oself.uploadFile = function(fo) { oself.calcNextChunkRange(fo); var blob, simple_upload = 0; try { blob = fo.slice(fo.currentChunkStartPos, fo.currentChunkEndPos - fo.currentChunkStartPos + 1); } catch(e) { // Safari doesn't support Blob.slice method blob = new FormData(); blob.append('Filedata', fo); simple_upload = 1; }; fo.xhr = new XMLHttpRequest(); fo.xhr.onreadystatechange = function() { if(this.readyState == 4) { try { if(this.status == 201) { // chunk was uploaded succesfully var range = this.responseText; try { // getResponseHeader throws exception during cross-domain upload, but this is most reliable variant range = this.getResponseHeader('Range'); } catch(e) {}; if(!range) { throw new Error('No range in 201 answer'); } fo.uploadedRange = range; // store range for case of later retry fo.retry = oself.opts.maxChunkRetries; // restore retry counter userStorage.set(fo); // add or update file info in localStorage oself.uploadFile(fo); } else if(this.status == 200) { fo.responseText = this.responseText; fo.loaded = fo.size; // all bytes were uploaded userStorage.del(fo); // delete file info from localStorage oself.broadcast('onDone', fo, fo.responseText); } else if(this.status == 0 && fo.cancel == 1) { //t('Aborted uploading for id=' + fo.id); } else { throw new Error('Bad http answer code'); } } catch(e) { // any exception means that we need to retry upload oself.retryUpload(fo); }; } }; fo.xhr.open("POST", fo.full_url, true); fo.xhr.upload.onprogress = function(evt) { fo.loaded = (simple_upload ? 0 : fo._loaded) + evt.loaded; oself.broadcast('onProgress', fo); }; if(!simple_upload) { fo.xhr.setRequestHeader('Session-ID', fo.sessionID); fo.xhr.setRequestHeader('Content-Disposition', 'attachment; filename="' + encodeURI(fo.name) + '\"'); fo.xhr.setRequestHeader('Content-Range', 'bytes ' + fo.currentChunkStartPos + '-' + fo.currentChunkEndPos + '/' + fo.size); fo.xhr.setRequestHeader('Content-Type', 'application/octet-stream'); } fo.xhr.withCredentials = true; // allow cookies to be sent fo.xhr.send(blob); };
ã³ãŒãå ã®ã³ã¡ã³ãã¯ãSafariãã©ãŠã¶ãŒïŒå°ãªããšãWindows OSäžïŒã§ã®html5 File APIã®äžå®å šãªãµããŒããæ確ã«ç€ºããŠããŸãã泚ãåç § 3ã
ãšã©ãŒãçºçãããšãretryUploadã¡ãœãããèµ·åãããããŒãããŒããŒã®åæåäžã«æå®ãããåæ°ã ããã¡ã€ã«ã®ããŠã³ããŒããç¹°ãè¿ãè©Šè¡ãããå倱æã®è©Šè¡ééãé·ããªããŸãã
è©Šè¡åæ°ã䜿ãæãããšãonErrorã€ãã³ããçæãããŸãã
oself.retryUpload = function(fo) { fo.retry--; if(fo.retry > 0) { var timeout = oself.opts.retryTimeoutBase * (oself.opts.maxChunkRetries - fo.retry); setTimeout(function(){oself.uploadFile(fo)}, timeout); } else { oself.broadcast('onError', fo. lwu.ERROR_CODES.OTHER_ERROR); } };
ãã®å¥è·¡ããã¹ãŠæ©èœããããã«ã¯ã ã¢ããããŒãã¢ãžã¥ãŒã«ãåããnginxããµãŒããŒã«ã€ã³ã¹ããŒã«ããå¿ èŠããããŸãã ããã«ã€ããŠããå°ã詳ããã¯ã åã®èšäºã§èª¬æããŸãã ã
ããšããã®ä»£ããã«...
ããã€ãã®èããè¿°ã¹ãããšæããŸãã
1.çŸæç¹ã§ã¯ãFileAPIã¯Chrome 8以éãFirefox 4ããŒã¿çãéšåçã«
ããããè¿·æãªãã°ã®ããã«Chrome 8ããªãã«ããŸããããã®ããããã€ã¢ãã°ã§å€ãã®ãã¡ã€ã«ãéžæããããšã¯äžå¯èœã§ãã
Firefox 3ã¯ç¬èªã®æ¹æ³ã§FileAPIããµããŒãããŠããŸããç·æ¥ã«å¿ èŠãªFormDataãªããžã§ã¯ãã¯ãµããŒããããŠããªãããã倧ããªãã¡ã€ã«ãããŠã³ããŒãããããšã¯ã§ããŸããã ãã¡ã€ã«ã®å å®¹å šäœãã³ã³ãã¥ãŒã¿ãŒã®ã¡ã¢ãªã«èªã¿èŸŒãå¿ èŠããããŸãã
2. acceptå±æ§ã¯éåžžã«äžåšçšã«æ©èœãããã©ãŠã¶ã¯å€ãã®MIMEã¿ã€ããç解ããŸããã ãããã£ãŠããªããã£ã«ã¿ãªã³ã°ããã®ããã«è¡ãããã®ããæ¡åŒµæ©èœã®ãªã¹ãã«åŸã£ãŠã§ã¯ãªããFlashããã³Silverlightã§è¡ãããã®ã¯ãç§ã«ã¯è¬ã®ãŸãŸã§ãã
3. Safariãã©ãŠã¶ãŒã¯FileReaderãªããžã§ã¯ããšBlob.sliceã¡ãœãããå®è£ ããªããããhtml5ã®ãªããŒãã¯æ©èœããŸããã ãªããŒãã¯éåžžã«äŸ¿å©ãªããã³ããªã®ã§ãSafariã§ããŒããŒãããŒãããé åºãå€æŽããSilverlightãããæãŸãããã®ã«ããŸããã
4.å®å šã«æããã§ã¯ãããŸãããããããæŒç®ã䜿çšããå ŽåãJavascriptã¯ãªãã©ã³ãã笊å·ä»ãint32åã«å€æããŸãã ãããŠä»¥æ¥ Adler32ãã§ãã¯ãµã ãèšç®ããã«ã¯ã笊å·ãªãã®æ°å€ãå¿ èŠã§ããå·Šãžã®ãããã·ãããæŸæ£ãã65536ã®ä¹ç®ã䜿çšããå¿ èŠããããŸããã
5.ã¯ã©ã€ã¢ã³ãã§ãã¡ã€ã«åã®URIãšã³ã³ãŒããè¡ãããµãŒããŒã§ãã³ãŒãããå¿ èŠããããŸãã ååã¯Content-DispositionããããŒã«åé¡ãããããããŒã«ã¯æšæºã§éASCIIæåãå«ããããšã¯ã§ããŸããã
6.å¿ ãFirebugãã©ã°ã€ã³ãªã©ãç¡å¹ã«ããå¿ èŠãããããšããŠãŒã¶ãŒã«èŠåããŠãã ããããã®çç±ã¯æ¬¡ã®ãšããã§ãã[ãããã¯ãŒã¯]ã¿ãã®Firebugã¯ããã¹ãŠã®ãããã¯ãŒã¯ã¢ã¯ãã£ããã£ãèšé²ãããã¹ãŠã®ãªã¯ãšã¹ããå®å šã«ä¿åããŸãã ãªã¯ãšã¹ãã®ãµã€ãºã¯å°ããããããã©ã°ã€ã³ã®ãã«ãã€ã³ãªããã¿ãŒã¯æ©èœããã倧ããªãã¡ã€ã«ã§ã¯ãã©ãŠã¶ãŒã倧éã®ã¡ã¢ãªãæ¶è²»ããŸãã
Files Mail.Ruã®äž»èŠãªéçºè ã§ããDmitry Dedyukhin