Extensible Web ãæ¯ããä½ã¬ãã« API 群
Intro
æè¿ Extensible Web ã®è©±ããã¾ã«åºãããã«ãªãã¾ãããããªãã¨ãããã¬ã¤ã¤ã®é«ãæ¦å¿µ(ãã¨ã )çãªè©±ãå¤ãæ°ããã¦ã¾ãã
ããå°ãå ·ä½ç㪠API ã¨ãããããã³ã¼ãæ¸ãä¸ã§ä½ãå¤ããã®ï¼ãã£ã¦è©±ããã¾ããªãã®ã§ãä»æ¥ã¯ããã«ãã©ã¼ã«ã¹ãã¦ã Extensible Web çãªæµãã®ä¸ã§æ´çããã API ã®è©±ããã¾ãã
ããããå®éã«ã¯ API ã ãExtensible Web ã¨ããç念ã§çã¾ãããã©ãããã¯èªæã§ã¯ãªãã®ã§ã ä»æ¨æºåããã¦ããä½ã¬ãã«ãª API ãæ¾ãããããæ´çããã¨ããã¨ã³ããªã ã¨æã£ã¦ããã¨è¯ãããããã¾ããã
ãã¾ãç¥ããã¦ãªã API ãããã¨æãã®ã§ããããæã«ããããããã°ãä»ã¾ã§ã§ããªãã£ãã¢ã¬ããæ¨æºåãå®è£ ãå¾ ããªãã¦ããã§ããããã«ãªããªãã¨æã£ããæ¯éæ¸ãã¦ã¿ãã¨è¯ãã¨æãã¾ãã å®éã¯ããããã Extensible Web ã®ç®æãã¨ãããªã®ã§ã
Extensible Web ã¨ã¯
å¹´æ«ã«ã¨ã³ããªãæ¸ãã¾ããã
Extensible Web ã®å¤æãã¨éçºè ãå¾ãå¯è½æ§ã®è©±
ã㨠mozaic.fm | #15 Extensible Web ã§ãå ¨é¨è©±ãã¦ãã¾ãã
ç°¡åã«è¨ãã¨ããããªæãã®æ¹éã§ãã
足ã®é ãæ¨æºåããæéã®ããããã©ã¦ã¶å®è£ ãå¾ ããã«ã éçºè ãèªåã®ã¢ã¤ãã¢ãã³ã¼ãã§å®ç¾ã㦠Web ãé²åãããããããã«ã å¿ è¦ãªæ©è½ãã¢ãã«åãããã®ã¢ãã«ã«ã¢ã¯ã»ã¹ãã ä½ã¬ãã«ãª API ãæä¾ããããã«ãããã
åºå ¸ã¯ The Extensible Web Manifesto ã¨ãã 2013 å¹´ã®ãããã§ã¹ãã§ã ããããå¾ã ã«ãã®æ¹éã«åã£ãã¨æããã API ãæ´åãããã ãã ãå®è£ ã¾ã§éãã¦æ¥å§ããã¨ãããã§ã¼ãºã§ãã
(å æ¥ ãããã§ã¹ãã®ç¿»è¨³ ãæ¬å®¶ã«åãè¾¼ãã§ããã£ãã®ã§åããã¦ã©ããã)
TOC
- HTML æ¡å¼µç³» API (WebComponents)
- Custom Elements
- ãã¤ããªç³» API
- ArrayBuffer / ArrayBufferView / DataView
- Blob
- Encoding
- ãããã¯ã¼ã¯ç³» API
- ãªãã©ã¤ã³ç³» API
- Service Workers
- Caches
- URL ç³» API
- URLSearchParams
- FormData
- éåæå¦çç³» API
- Promise
- Streams
- ä½ã¬ãã« API ã¨ã®åãåãæ¹
ãªã³ã¯è²¼ããããªãã
HTML æ¡å¼µç³» API (WebComponents)
ä¾ãã° HTML èªä½ã«æ°ããã¿ã°ã追å ããã¨ãªãã°ã W3C/WHATWG ã§æ¨æºåããå¿ è¦ãããã¾ããã ãããéçºè ãã³ã¼ãã§æ°ããç¬èªã®ã¿ã°ãå®ç¾©ãããã®æåã JS ã§å®è£ ã§ããããã«ãªãã¾ããã
ããã WebComponents ã¨å¼ã°ãã API é¡ã§ãã
Custom Elements
ã¿ã°åã« -
ãã¤ããå¿
è¦ãããã¾ãããæ°ããã¨ã¬ã¡ã³ã(ã¿ã°)ãå®ç¾©ãããã¨ãã§ãã¾ãã
ã¾ããæ°ããã¿ã°ãå®ç¾©ããªãã£ãã¨ãã¦ããæ¢åã®ã¿ã°ãæ¡å¼µãã¦ããã®ã¿ã°ã«å¯¾ãã¦æ©è½ã追å ãããã¨ãã§ãã¾ãã
ä»ã¾ã§ã¯ãç¬èªã®ã¿ã°ãå®ç¾©ããæ¨æºçãªæ¹æ³ããªãã£ãããã div / span ãªã©ã®æ±ç¨ã¿ã°ã« class å±æ§ãªã©ãä»ããããã§æ¡å¼µããæåãªã©ãå®ç¾©ãã¦ãã¾ããã
ãããã CustomElement ãç¨ããã¨ãä»»æã®æåãå®è£ ãããªãªã¸ãã«ã®ã¨ã¬ã¡ã³ããå®ç¾©ãããã¨ãã§ãã¾ãã ãããç¨ããã¨ãå®å ¨ã«ç¬èªãªã¨ã¬ã¡ã³ãããæ¨æºåããã©ã¦ã¶ã®å®è£ ãå¾ ããã«å®ç¾©ãããã¨ãã§ããã®ã§ãã
var xFoo = document.registerElement('x-foo'); // xFoo ã«æåãå®ç¾© // ãªãªã¸ãã«ã®ã¨ã¬ã¡ã³ããä½æ // <x-foo></x-foo>
ããããHTML ã®æ¢åã®ã¿ã°ã¯æ¢ã«ããªãã®ãã¦ãã¦ã¨å®ç¸¾ãæã£ã¦ãããããããããç¡è¦ããå®å ¨ã«ãªãªã¸ãã«ãªã¨ã¬ã¡ã³ããä½æãã¦ãããããå¾æ¥ã® Web ã¨èªç¶ãªå½¢ã§é¦´æãã¨ããã¾ã§ä½ãè¾¼ãäºã¯å®éã«ã¯é£ããã§ãã
ããã§ããã©ã¦ã¶ãæ¨æºã§å®è£ ãã¦ãããã®ããã¼ã¹ã¨ããæ¡å¼µæ©è½ãå®ç¾©ãããã¨ãã§ãã¾ãã ãã®æ¹æ³ã¯ããã CustomElements ã«ãã©ã¦ã¶ã対å¿ãã¦ããªãã¨ãã¦ããé常ã®ã¿ã°ã®åä½ã«ãã©ã¼ã«ããã¯ã§ããã¨ããã¡ãªãããããã¾ãã
document.registerElement('x-form', { extends: 'form', prototype: Object.create(HTMLFormElement.prototype) }); // æ¢åã®ã¨ã¬ã¡ã³ããæ¡å¼µ // <form is="x-form"></div>
ã¿ã°ãå®ç¾©å¯è½ãª API ã§ãããã¨ãå©ç¨ãããHTML ã®æ¨æºã¨ã¬ã¡ã³ãã Custom Element ã§åå®è£ ãããã¨ããå®é¨ããã¸ã§ã¯ããããã¾ãã
https://github.com/domenic/html-as-custom-elements
ããã«ããã以ä¸ã調ã¹ãåãçµã¿ã®ããã§ãã
- Web ã®æã¤æ©è½ãåç¾å¯è½ãã調ã¹ããã¨ã§ã足ãã¦ãªã API ãç¡ããã調ã¹ãã
- Custom Elements ã® API ãããã©ãããã©ã¼ã ãåç¾ãããã®ã¨ãã¦ååãªãã¶ã¤ã³ããæ¤è¨¼ããã
ã¤ã¾ãã Custom Elements ã¯ã Web ãæ㤠HTML ã¨ã¬ã¡ã³ãã¨ããä½ã¬ãã«ãªè¦ç´ ãã API ãç¨ãã¦åæ§ç¯å¯è½ãªã¾ã§ã«ä½ã¬ãã«ãª API ãç®æãã¦ãã¾ãããããã¦éçºè ããåºã¦ããæ°ããã¨ã¬ã¡ã³ããæç¨ã§ããã°ãæ¨æºåã®ããã»ã¹ãçµã¦ãã©ã¦ã¶ã«å®è£ ãããããããã¾ããã
ãã ããã¨ã¬ã¡ã³ããå®è£ ããã«ã¯ãæ¢åã® DOM ããªã¼ã«ä¾åããªãã¹ã¿ã¤ã«ã®é©ç¨ãããã®å®ç¾©ãèªã¿è¾¼ãæ©è½ã欲ãããªãã¾ãã ãããã足ãã¦ãªãé¨åãè£ãããã«ã以ä¸ã® 3 ã¤ã® API ãæ°ãã«æä¾ãããä¸è¬çã«ã¯ãããã¾ã¨ã㦠WebComponents ã¨å¼ãã§ãã¾ãã
http://w3c.github.io/webcomponents/spec/custom/
ãã¤ããªç³» API
JS ã¯é·ããããã¤ããªãã¼ã¿ãæ±ãæ¨æº API ãããã¾ããã§ããã ç¹ã« WebGL ã®å°å ¥ã«ä¼´ãããããã API ã®éè¦ãå¼·ããã£ãã¨ããçµç·¯ããããããªã®ã§ã Extensible Web ãããå°ãåãªæ°ããã¾ãããéè¦ãªä½ã¬ãã« API ã§ãããä»ã®ä½ã¬ãã« API ãããã«ä¾åãããã®ãå¤ãã®ã§ãããããã¦æ´çãã¦ããã¾ãã
ArrayBuffer / ArrayBufferView / DataView
ArrayBuffer ã¯ãã¤ããªãã¼ã¿ãè©°ãè¾¼ã¾ãããèªã¿åãå°ç¨ã®ãã¤ãé åã§ãã ãã¤ããªãã¼ã¿ãè¿ã API ãªã©ã¯ããã® ArrayBuffer ã®å½¢å¼ã§è¿ããã®ãããã¾ãã
å®éã« ArrayBuffer ãããã¤ããªãã¼ã¿ãåãåºãã®ã ArrayBufferView ã§ãã ãã JavaScript ã« uint8 ã int32 åãªã©ã®ããµã¤ãºåºå®ãªæ°å¤åãå®ç¾©ã§ããã°ããã®åã§å®£è¨ããå¤æ°ã«ãã¼ã¿ãåãåºãã¨ãã£ããã¨ãã§ãã¾ããã JavaScript ã«ã¯ number åãããªããããã®æ¹éã¯ã¨ãã¾ããã
ããã§ã ArrayBuffer ã«è©°ãè¾¼ã¾ãããã¤ããªãã¼ã¿ã uint8 ã int32 ã¨ãã£ã Chunk ãã¨ã«åºåãããé åã¨ã¿ãªãã ãã®é åãããã¼ã¿ãåãåºããçµæãæ±ãããµã¤ãºã® number ã«ãªã£ã¦ããã¨ããæ¹éãã¨ãã¾ãã ãã®ä»»æã®ãµã¤ãºã« ArrayBuffer ãåºåãããã«ãã¶ãã View ãã Uint8Array ã Int32Array ã¨ãã£ã ArrayBufferView ã«ãªãã¾ãã
Uint32Array: [ 4035938432] Uint16Array: [ 34944, 61583] Uint8Array: [ 128, 136, 143, 240] ArrayBuffer: [ 1000000, 10001000, 10001111, 11110000]
ãããã ArrayBufferView ã¯åºå®é·ã«åºåããããã¼ã¿ãæ±ãã«ã¯åãã¦ãã¾ããããã¨ãã°ãããã¯ã¼ã¯ããã¡ã¤ã«ã®ãããªããããã«ããæ§ã ãªã®ãµã¤ãºã®æ å ±ãèªã¿è¾¼ããããªå ´åã«ã¯ããã®ãã³ã« View ã®åãå¤ããå¿ è¦ãã§ã¦ãã¾ãã¾ãã
ããã§ãããããã¿ã¤ãã®ãã¼ã¿ã¯ DataView ãç¨ãã¾ãã DataView 㯠getUint8()
, getInt32()
ã¨ãã£ãå
·åã«ãã¼ã¿ãæå®ãµã¤ãºã§é½åº¦åãåºããããããã±ããã®è§£æãªã©ã«é©ãã¦ãã¾ãããã¡ãã setter ã使ãã°ããã¼ã¿ãéã/æ¸ãå´(ãµã¼ããªã©)ã«ä½¿ããã¨ãã§ãã¾ãã
ArrayBuffer: [ 1000000, 10001000, 10001111, 11110000] getUint8(0): 128 getUint16(0): 32940 getUint32(0): 2156433392
ãã® ArrayBuffer, ArrayBufferView, DataView ãåããã¦ãä¸è¬ã« TypedArrays ã¨å¼ã°ãã¦ãã¾ãã å¾è¿°ããå¤ãã® API ããã¤ããªãä½ããã®å½¢ã§æ±ã£ã¦ããããã®å ´åãã® TypedArrays ãç¨ãããã¨ã«ãªããããé常ã«éè¦ãªä½ã¬ãã« API ã¨è¨ããã¨ãã§ãã¾ãã
https://www.khronos.org/registry/typedarray/specs/latest/
Blob
ãã©ã¦ã¶ä¸ã®ãã¤ããªãã¼ã¿ã®åºã¾ããæ±ããªãã¸ã§ã¯ãã§ãã æååã ArrayBuffer, ArrayBufferView ãªã©ããã¨ã«çæãã¾ãã
ãã¤ããªãã¼ã¿ãããã©ã¦ã¶ã¨ããä¸çãã«æã£ã¦ããéã«ã«çµç±ãããå°å³ã ãã©é常ã«éè¦ãª API ã§ãã
ç¹å¾´ã¯ URL.createObjectURL() ã«æ¸¡ã㨠URL ãçæã§ãããã¨ã§ãã ãã㯠img, video ãªã©ã® src ã®å¤ãã xhr ãªã© URL ãæ±ã API ã«ãã®ã¾ã¾æ¸¡ããã¨ãããã¨ã§ãã ãã¼ã¿ã®åºæ¬ã§ãããã¤ããªãªãã¸ã§ã¯ãããã©ã¦ã¶ãåºæ¬è¦ç´ ã¨ãã¦æ±ã URL ã«å¤æã§ããäºã«ãã£ã¦ãå ¨ã¦ã®ãã¼ã¿ããã©ã¦ã¶ã¨ç¹ãããã¨ã«ãªãã¾ãã
ä¾ãã° File ãªãã¸ã§ã¯ãã Blob ã®æ¡å¼µã¨ãã¦æãç«ã£ã¦ããã URL ã«å¤æãã¦ã㦠<a> ã® href ã«ç¹ããã¨ã§ãã¦ã³ãã¼ãã§ãã¾ãããã㯠<a> ã® href ã®æ±ããæ¢ã«ãã©ã¦ã¶ä¸ã§è¦å®ããã¦ãããããã«ä»»æã®ãã¤ããªãã¼ã¿ã URL ãä»ãã¦æ¥ç¶ã§ãã¦ããäºãæå³ãã¾ãã
var blob = new Blob(arrayBuffer, { 'type' : 'audio/mp3' }); // ãã¤ã㪠var url = URL.createObjectURL(blob); // URL document.querySelector('a').href = url; // ãã¡ã¤ã«ããã¦ã³ãã¼ãããã
èªåã§ä½ããã¤ããªãæ±ã API ãèããå ´åã«ãåºç¤ã¨ãã¦ä½¿ããã¨ãã§ãã¾ãã
https://developer.mozilla.org/en-US/docs/Web/API/Blob.Blob
Encoding
ä»ã¾ã§ String.prototype.charCodeAt()
ã String.fromCharCode()
ã ES6 ã§ã¯ String.fromCodePoint()
ãªã©ã§ãæåã Unicode ã® code point ã¨ç¸äºå¤æãããã¨ãã§ãã¾ããããä»»æã®ã¨ã³ã³ã¼ãã¨ã®å¤æã¯ãã¤ããªæä½ã«ãã£ã¦èªåã§è¡ãå¿
è¦ãããã¾ããã
Encoding API ãç¨ããã¨ãæååããæåã³ã¼ãã«å¿ããããã¤ããªãã¼ã¿ã¨ç¸äºå¤æã§ãã¾ãã ã¤ã³ã¿ãã§ã¼ã¹ã¯ãå é¨ã®ã¨ã³ã³ã¼ãã£ã³ã°å½¢å¼ãããããã«æã¤äºãã§ããããã« TextEncoder/TextDecoder ã«åããã¦ãã¾ãã
TextEncoder 㯠'utf-8', 'utf-16be', 'utf-16le' ã®ã¿ã«å¯¾å¿ãã¦ããã encode() 㧠String ããã®æåã³ã¼ãã® Uint8Array ã«å¤æãã¾ãã
var utf8 = new TextEncoder('utf-8'); utf8.encode('ã'); // [227, 129, 130]
ã¨ã³ã³ã¼ãããæåã³ã¼ããéå®ããã¦ããã®ã¯ã Web ã«ããã¦åºæ¬çã«ãããã®æåã³ã¼ããã使ããªãããã«ãããããã§ãã Web ã®ä¸çã§ã¯ãã utf-8 以å¤ã使ããã¨ã¯ã極åé¿ãã¦è¡ãã¹ãã¨ããæ¨ãä»æ§ã«ãæ¸ããã¦ãã¾ã(https://encoding.spec.whatwg.org/#preface)ã
TextDecoder ã¯ããªãå¤ãã®æåã³ã¼ããæå®ãããã¨ãã§ãã decode() 㧠Uint8Array ã String ã«å¤æãã¾ãã (ã©ã®ãããå¤ããã¯ã https://encoding.spec.whatwg.org/encodings.json ãè¦ãã¨ãããã¾ããã¬ã¬ã·ã¼ãªæåã³ã¼ãããã¡ãã¨ã«ãã¼ããã¦ã¦æ¬å½ã«ãããã)
ä¾ãã° shift-jis ã ã¨ä»¥ä¸ã®ãããªæãã§ãã
var shiftjis = new TextDecoder('shift-jis') shiftjis.decode(new Uint8Array([130, 160])) // 'ã'
ãã³ã¼ãã§ã¯å¤ãã®å½¢å¼ã対å¿ãã¦ããã®ã¯ãä¾ãã°ä»»æã®ããã¹ããã¡ã¤ã«ã File API ã§èªã¿è¾¼ãã§ããã®å 容ã表示ããã¨ãã£ãå ´åã«ãå¤ãã®ã¨ã³ã³ã¼ãã£ã³ã°ã«å¯¾å¿ããå¿ è¦ããã£ããããã¨æãã¾ãã utf-8/16 以å¤ã®æåã³ã¼ãã®æå㯠Blob ã¨ãã¦åå¾ãã utf-8 ã®æåã«ç´ãã¦ããå¥ã®å¦çãè¡ãã¨ãã£ãå½¢ã«ãªã£ã¦ããã¨æãã¾ãã
ã¾ãã utf-8 å¤ãåå¾ã§ãããããéæ¨å¥¨ãª escape() ã®å¤ããã« UTF8 ãã¼ã»ã³ãã¨ã³ã³ã¼ãã£ã³ã°ãªã©ãå¯è½ã«ãªãã¾ã(ã¨ã³ã³ã¼ãã㦠toString(16).toUpperCase() ã㦠'%' ãã¤ããã ã)ã
https://encoding.spec.whatwg.org
ãããã¯ã¼ã¯ç³» API
Fetch
ãã©ã¦ã¶ããçºçãããããã¯ã¼ã¯ã¢ã¯ã»ã¹ã¯åºæ¬çã«ã¯ HTTP ã§ãã ããããåç´ãª HTTP/1.1 GET ãªã¯ã¨ã¹ãã¯ã telnet ãªã©ã§çºè¡ããã° 3 è¡ç¨åº¦ã§æ¸ã¿ã¾ããã ãã©ã¦ã¶ã¯ãã©ã¦ã¶ç¹æã®æ§ã ãªæåã追å ããããããä¸è¦åç´ãª GET ã§ãè¤éãªãªã¯ã¨ã¹ãã«ãªãã¾ãã
ä¾ãã°ä»¥ä¸ã®ãããªãã®ã§ãã
- UA ãèªåã§ä»ä¸ããã
- ãªãã¡ã©ãä»ä¸ããã
- Cookie ãä»ä¸ããã
- ãã©ã¦ã¶ããã£ãã·ã¥ã管çããä»éãããããå¦çããã
- CORS ã®å¶éãé©ç¨ããã
- å¿ è¦ã«å¿ãã¦èªå㧠preflight ãçºçãã
- etc
ãããããã©ã¦ã¶ç¹æã®æåãå å³ãã¦çºè¡ããã HTTP ãªã¯ã¨ã¹ãã§ããã©ã¦ã¶ã¯ãµã¼ããããªã½ã¼ã¹ãåå¾ãã¾ãããã®è¡çºã Fetching ã¨å¼ãã§ãã¾ãããããã®è¡çºã¯ XHR ã CORS ã«ãã£ã¦ã©ãã©ãè¤éã«ãªã£ã¦ãã¾ããã
Fetch ã®ä»æ§ã¯ ããã©ã¦ã¶ã Fetch ããã¨ã¯ã©ããããã¨ãï¼ãã¨ããæ¦å¿µããã¡ãã¨æ´çãã¦å®ç¾©ãã¦ããããã®æå°éã® API ã¨ãã¦å®è£
ãããã®ã fetch()
API ã§ãã
fetch()
㯠XHR ã¨éã Promise ãè¿ã API ã§ãããã¨ãããåã«ã¢ãã³ãªæãã«ããã ããã¨æãããã¡ã§ããã fetch()
å°å
¥ã«ä¼´ã£ã¦ä»¥ä¸ãå¤ãã£ã¦ãã¾ãã
- Request, Response, Header ãªã©ã®ã¯ã©ã¹ãå®ç¾©ããã
fetch()
èªä½ã¯ãªãã¸ã§ã¯ãã§ã¯ãªãåãªãé¢æ°- chache ã origin ã credential ãªã©ç´°ããªå¶å¾¡ãå¼æ°ã§å¯è½ã«ãªã£ã
- Promise ãè¿ã
ãããã£ã¦ããã©ã¦ã¶ãããã©ã«ãã§çºè¡ãããªã¯ã¨ã¹ãã¨åçãªãã®ãç¨ãããããã¯ã¼ã¯ã¢ã¯ã»ã¹ãå¿ è¦ãªã©ã¤ãã©ãªãªã©ãæ¸ãå ´åã¯ãç¶ã足ãã§ä½ããã XHR ã®å¤ããããã¤ã³ã¿ãã§ã¼ã¹ã«ã¨ããããäºç¡ãå®è£ ãã§ãã¾ãã
fetch('http://my.api.org/', { method: 'post', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ user: 'Jxck' }), credentials: 'cors', chache: 'force cache' }).then(res => { console.log(res.url, res.type, res.status); if(res.headers.get('content-type') === 'application/json') { res.json().then(json => console.log(json)); } else { // res.arrayBuffer(); // res.blob(); res.text().then(text => console.log(text)); } }).catch(err => console.error(err));
注æç¹ã¨ãã¦ã¯ãä»ã¯ã¾ã abort()
ãç¡ãã Promise ãè¿ãã®ã§ onprogress
ç¸å½ãããã¾ããã
ããã¯ä»å¾ CancelablePromise ã Stream ãªã©ã®è°è«ã¨ã¨ãã«é²ãã§ããäºå®ã®ããã§ãããããå®è£
ã§ããã¨ã XHR 㯠fetch ã使ã£ã¦å®å
¨ã«åç¾ã§ããçã§ãã
TCP and UDP Socket API
WebSocket ã¯ãWeb ä¸ã§ã®åæ¹åéä¿¡ããç®çã¨ãã¦ããç´ç²ãª TCP ã§ã¯ãªããã WebRTC ã¯ãWeb ä¸ã§ã® P2Pããç®çã¨ãã¦ããç´ç²ãª UDP ã§ã¯ããã¾ããã fetch() ã¯ããã©ã¦ã¶ããã®ã HTTP ãªã¯ã¨ã¹ãã¨ãã¦ä¸çªä½ã¬ãã«ã§ããã
ããã§ããããã£ã TCP/UDP ã®ã½ã±ãã API ããã®ã¾ã¾ãã©ã¦ã¶ãã使ããããã«ãã¦ãã¾ããã¨ããæãã®ã³ã³ã»ããã§ãã Socket API 㯠TCP/UDP ã¸ã® write() ã¯ãã¡ããã listen() ãã§ãã¾ããã¤ã¾ããµã¼ããç«ã¦ã¦ãã¾ãå¯è½æ§ãããã®ã§ãã
// write var client = new TCPSocket('http://example.com', 80); client.writeable.write('ping').then(() => { client.readable.wait().then(() => { console.log(client.readable.read()); }); }); // listen var server = new TCPServerSocket({'localPort': 300}); server.listen().then((connection) => { connection.readable.wait().then(() => { console.log (connection.readable.read()); }); });
ä¾ãã° MQTT ãªã©ã WebSocket ä»ããå®è£ ããããç¾å¨è°è«ä¸ã® ORTC ã®ãããªãã®ã PoC å®è£ ãããããéã«ä½¿ããã ãã§ãªãã ãã©ã¦ã¶ãç©ãã ããã¤ã¹ãã ServiceWorker å 㧠TCP ãµã¼ãç«ã¦ããã DNS ã®åå解決ãããªãã¦ãã¨ãã§ãã¦ãã¾ãããããã¾ããã
ãã©ã¦ã¶ã®ã¬ãã«ã¾ã§ãã® API ãæã£ã¦ããäºã¯ãã»ãã¥ãªãã£ã®ãµã³ãããã¯ã¹åãé常ã«æ°ã«ãªãã¨æãã¾ãã確ãã«å¾æ¥ OS ãæ±ã£ã¦ããã¬ãã«ã¾ã§ä¸ãã£ã¦ãã Socket API ã®å®è£ ã§ã¯ãããé常ã«éè¦ã«ãªãã¾ãã ãã㧠Extensible Web ã®ä¸ã«ã¯ãããããããæ¨æºåããªã½ã¼ã¹ãè£ãã¹ãã¨ããã ãã¨æè¨ããã¦ãã¾ããé«ã¬ãã« API ã®çå®ã§ã¯ãªãã»ãã¥ãªãã£çã«å®å ¨ãªä½ã¬ãã« API ã®æä¾ã«æ³¨åããã¹ãã¨ããæ¹éã§ãã
ä¸æ¹ã§ãä¾ãã° raw socket ãæ±ãã³ã¼ãã JS ã§å®çµããã¨ãä»ã¾ã§æ¡å¼µããã©ã°ã¤ã³ã§ç¡è¶ããã³ã¼ãã®ã»ãã¥ãªãã£ãã¼ã«ã«ãã£ã¦çºçãã¦ããããã¤ãã£ã層ã¾ã§çªãæãããããªèå¼±æ§ããæ¸å°ããå¯è½æ§ãèãããã¾ãã
http://www.w3.org/TR/raw-sockets/
ãªãã©ã¤ã³ç³» API
ãªãã©ã¤ã³åããããã«å¿ è¦ãªæ©è½ãã¢ãã«åããã¨ä»¥ä¸ã®ä¸ã¤ã«å¤§å¥ãããã¨ãã§ãã¾ããã
- é常㮠JS ã®ã³ã³ããã¹ãã¨ã¯ãå¥ã®ã³ã³ããã¹ã(ã¹ã¬ããã¨è¨ã£ã¦ãæ¦ãè¯ã)㧠JS ãåããç°å¢ (service worker)
- ãã£ãã·ã¥ãä¿æããæ©è½ (cache)
- ãã©ã¦ã¶ã®ãªã¯ã¨ã¹ããåç¾ããæ©è½ (fetch)
ããããåãã㦠ããªãã©ã¤ã³ Web ãå®ç¾ãã APIãã ã¨ããã¦ããæãããã¾ãããããã¯ä½¿ãæ¹ã®å¡ä¾ã®ä¸ã¤ã§ãã åã ã¯å¥ã«ãã¥ã¼ããªã¢ã«ã«æ¸ããã¦ãéãããªãã©ã¤ã³åããããã«ãããã使ããªãããã§ã¯ããã¾ããã
Service Workers
ãã©ã¦ã¶ã® JS ã¨ã¯å¥ã®ã³ã³ããã¹ãã§åä½ãã(å¥ã®ã¹ã¬ãããç«ã£ã¦ããã¤ã¡ã¼ã¸)ç°å¢ãæä¾ãã¾ãã ããã ããªã WebWorker ã¨åãã§ããã SW ã¯ãã©ã¦ã¶ã¨ãããã¯ã¼ã¯ã®éã«æã¾ã Proxy ã®ããã«åä½ãã¾ãã
ä¾ãã°ããã©ã¦ã¶ä¸ã§çºçãã HTTP ãªã¯ã¨ã¹ã(ã¤ã¾ã Fetch) ãã¤ãã³ãã§æ¤ç¥ãããã¨ãã§ãããã å¤ãã Push API ã§é£ãã§æ¥ãã¡ãã»ã¼ã¸ãã¤ãã³ãã§åãåããã¨ãã§ãã¾ãã
ãã©ã¦ã¶ã¨ã¯ç¬ç«ããã³ã³ããã¹ãã§ããã©ã¦ã¶ã®è£ã§ã¡ã¿ãªå¦çãå¯è½ãªç°å¢ãæä¾ããã®ãã SW ã®æ¬è³ªã§ãã ãã®äºããµã¾ãã¦ãããè¨ããã¦ããããªãã©ã¤ã³ã¢ããªããããããã·ãã¨ãã¦ä½¿ãäºãã§ããã¨ããã ãã§ãã£ã¦ããã使ããªãã¨ãããªãã¨ãããã®ã§ã¯ããã¾ããã
// ç»é²ãã SW å 㧠this.addEventListener('fetch', (e) => { // ãã©ã¦ã¶ã§çºçãã fetch (ãªã³ã¯ã¯ãªãã¯ã XHR) ãåå¾ var req = e.request; // req ã«ç´°å·¥ req.header.set('x-foo', 'bar'); // ç´°å·¥ãããªã¯ã¨ã¹ãã fetch ã㦠response è¿ã e.respondWith(fetch(req).then((res) => res)); });
ãã®ããã« fetch()
ãä»å
¥ã§ããã®ã¯ã fetch ã®ä»æ§ã§ç´¹ä»ãã Request/Response/Header ã¯ã©ã¹ã«ãã£ã¦ããã©ã¦ã¶ã§çºçãã Request ãªãã¸ã§ã¯ããããã£ããããããç¨ã㦠fetch()
ãã¦å¾ã Response ããã©ã¦ã¶ã«è¿ãããã¨ããã¤ã³ã¿ãã§ã¼ã¹ãæ´ã£ãããã§ãã
https://slightlyoff.github.io/ServiceWorker/spec/service_worker/
Caches
å¤é¨ããåå¾ãããªã½ã¼ã¹ã®ãã£ãã·ã¥ã管çããããã®ãªãã¸ã§ã¯ãã§ãã ãã® API ã¯ç´ç²ã«ã Request ã«ã²ãã¥ãã Response ãä¿åã§ãã¾ãã
ãããã£ã¦ããã©ã¦ã¶ãçºè¡ãã Request ã«ãå¤ããã« fetch ãã Response ãä¿åããã¨ãã£ããã¨ãå¯è½ã«ãªãã®ã§ãã Request ããã¼ã«ãããªãã¸ã§ã¯ãã®ããã«æ±ããããã API ã®ç²åº¦ãç´°ããããã°ã©ããã«ã§ããã Application Cache API ã¨ã¯éããä¸é¨ã®ãªã½ã¼ã¹ã ããã£ãã·ã¥ãæ´æ°ããã¨è¨ã£ãäºãæè»ã«å¯è½ã§ãã
SW + Cache ã Application Cache API ã«å¤ãããªãã©ã¤ã³ã¢ããªã®ä½æã§æ³¨ç®ããã¦ããã®ã¯ãã®é¨åã§ãã
// request ã«ç´ã¥ãããã£ãã·ã¥ãè¿ã self.addEventListener('fetch', (e) => { event.respondWith(caches.match(e.request) .then((response) => response)); });
ãããããªãã©ã¤ã³åã®ããã«ãã使ã£ã¦ã¯ãããªã訳ã§ã¯ãªããä¾ãã°ãªã³ã©ã¤ã³ç¶æ ã§ãç´ç²ãªãã£ãã·ã¥ã¨ãã¦å©ç¨ãã¦ãããã©ã¼ãã³ã¹ã®åä¸ãªã©ãè¡ãäºãã§ãã¾ãã(ãã®å ´åã¯æ¬æ¥ã¯ cache-control ãããã使ãã¹ãã§ãã)
https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-objects
URL ç³»API
Web ã®åºæ¬ãã¤éè¦è¦ç´ ã§ãã URL ãã JS ããæ軽ã«æ±ããã¨ãã§ãã¾ãããªãã§ç¡ãã£ãã®ãã¨ããã¬ãã«ã§ãã å®ã¯é£ãã URL ã®ãã¼ã¹/ã·ãªã¢ã©ã¤ãºãå¯è½ã§ããã¼ã»ã³ãã¨ã³ã³ã¼ãã£ã³ã°ã punycodeã IPv6 ã Base Path ãªã©ãªã©ãã new ããã ãã§ã¾ãã£ã¨ãã£ã¦ããã API ã§ãã(ä»ã¾ã§ã¯ <a>ã¿ã°ã使ã£ã¦ç¡çç¢ç ããããèªåã§ãã¼ã¹ããããããã¾ããã§ããã)
var url = new URL('http://user:name@www.ãã¡ã¤ã³.com:8080/login?foo=bar#hash') url.hash; // "#hash" url.host; // "www.xn--eckwd4c7c.com:8080" url.hostname; // "www.xn--eckwd4c7c.com" url.href; // "http://user:[email protected]:8080/login?foo=bar#hash" url.origin; // "http://www.xn--eckwd4c7c.com:8080" url.password; // "name" url.pathname; // "/login" url.port; // "8080" url.protocol; // "http:" url.search; // "?foo=bar" url.username; // "user" URL.domainToAscii('ãã¡ã¤ã³å.com'); // 'xn--n8jwd4c7c.com' URL.domainToUnicode('xn--n8jwd4c7c.com'); // 'ãã¡ã¤ã³å.com'
domainToAscii()
㨠domainToUnicode()
ã«ã¤ãã¦ã¯ãå·çæç¹ã§å®è£
ãã¦ãããã©ã¦ã¶ã¯ãªããããªã®ã§ããµã³ãã«ã§ãã
ãã¼ã»ã³ãã¨ã³ã³ã¼ããªã©ããã¡ãã¨èæ
®ãããã®ã¯ã EncodingAPI ã«ãã£ã¦ utf-8 ããã¡ãã¨æ±ããããã«ãªã£ãããã¨è¨ãã¾ãã
注æç¹ã¨ãã¦ãæ¨æºã® DOM API ã¯ãã® URL ãªãã¸ã§ã¯ããå
é¨ã§ä½¿ãã©ãå¤ã«å
¬éããããã«ã¯ç¨ããªãã¨ãããã¨ã§ãã
å¤ã«å
¬éããå ´åã¯ãå¾æ¥éã URL ãæååã¨ãã¦å
¬éãã¹ãã¨ããæ¨ãæ¸ããã¦ãã¾ãã(https://url.spec.whatwg.org/#url-apis-elsewhere)
å®é fetch()
ãªã©ã¯å
é¨ã§ URL ãªãã¸ã§ã¯ãã使ã£ã¦ãã¾ããã Request ã¯ã©ã¹ãå
¬éãã¦ããã®ã¯æåååã® url ããããã£ã§ãã(https://fetch.spec.whatwg.org/#request-class)
çæéãªæ£è¦è¡¨ç¾ã§å¦çãã¦ããã¹ã¯ãªããã¯ãããã«ã§ããã®ã¯ã©ã¹ã§ç½®ãæããæ¹ãããã§ãããã ã¾ããæ°ããæ¸ãã©ã¤ãã©ãªãã URL æååãåãåããªããã¾ãæåã«ããã§ãã¼ã¹ããå ¬éæã« toString() ããããããè¯ãã¨æãã¾ãã
URLSearchParams
URL ã®ãã©ã¡ã¼ã¿é¨åãæ±ãããã®ãªãã¸ã§ã¯ãã§ãã
ã¾ãã Form ã POST ããã¨ããªã©ã«ä½¿ã form-urlencoded
å½¢å¼ã®è¡¨ç¾ãå¾ããã¨ãã§ãã¾ãã
é常ã«ã·ã³ãã«ãª API ã§ãããã·ãªã¢ã©ã¤ãºæã«ã¯é©åã«ã¨ã³ã³ã¼ããããæååãå¾ããã¾ãã
var params = new URLSearchParams('a=b&c=d&a=x'); params.has('a') // true; params.get('a') // 'b'; params.getAll('a'); // ['a', 'x'] params.delete('a'); params.append('ã', 'ã'); params.toString(); // 'c=d&%E3%81%82=%E3%81%84'
ããé©å½ã« &
ã =
㧠split()
, join()
, encodeURIComponent()
ãã¦ããå¦çããã£ãã¨ããã°ããã®å®è£
ã§ç½®ãæããäºã§ãã©ã¦ã¶ã¨å®å
¨ã«äºæãªå®è£
ã«ã§ãã¾ãã
èªåã§å®è£ ããã©ã¤ãã©ãªããã©ã¡ã¼ã¿ãæ±ãå ´åã¯çµ±ä¸ãã API ã¨ãã¦ããã使ãäºãèãããã¾ãã
ç¾æç¹ã§ã¯ XHR ã§ãã®ãªãã¸ã§ã¯ããç´æ¥ form-urlencoded
ã¨ãã¦éããªã©ã®ãã¨ã¯ã§ãã¾ããã
ããã ã¨ã¡ãã£ã¨å¾®å¦ãªã®ã§ãææ¡ãã¾ãããä» è°è«ä¸ ã§ãã
https://url.spec.whatwg.org/#interface-urlsearchparams
FormData
ãã®åã®éã Form ã® Data ãæ±ããªãã¸ã§ã¯ãã§ãã URLSearchParams ã¨ä¼¼ã¦ãã¾ããããã¡ã㯠DOM ä¸ã® Form ããç´æ¥çæããäºãã§ãããã®ã¾ã¾ XHR ã§éä¿¡ãå¯è½ã§ãã
ã¾ã DOM ã® Form ã <input type="file"> ã許容ããããã«ã
FormData ã«ã File ãªãã¸ã§ã¯ããå«ãäºãã§ãã¾ãã
ãªã®ã§ããã®ã¾ã¾ XHR 㧠send()
ããã°æ軽㫠File ã¢ãããã¼ããå¯è½ã§ãã
var form = document.getELemeneById('#login_form'); var formData = new FormData(form); xhr.send(formData);
æ°ãã¤ããªãã¨ãããªãã®ã¯ã FormData çµç±ã§éãã¨å¿
ã multipart/form-data
å½¢å¼ã«ãªãããããã¨ãæååãããªãã¦ã x-www-form-urlencoded
ã§éããããã° URLSearchParams ã«è©°ãæ¿ããå¿
è¦ãããã¾ãã(content-type ãæå®ãã¦ãç¡è¦ããã)
å ã»ã©ã®ææ¡ããå 容ã¯ãããã¨åãããã« Form ãã URLSearchParams ãçæã§ããããã«ããæ¹åã§åãã¦ããã®ã§ããããå®è£ ãããã以ä¸ã®ããã«ãªãã§ãããã
- URLSearchParams: ããã¹ãã®ã¿
x-www-formurlencoded
ç¨ - FormData: Blob è¾¼ã¿
multipart/form-data
ç¨
https://xhr.spec.whatwg.org/#interface-formdata
éåæå¦çç³» API
WHATWG ã§çå®ããã¦ããæ°ãã API ã§ãéåæãæ±ããã®ã¯åºæ¬çã«ã¯ Promise/Stream ãã¼ã¹ã§è¨è¨ããã¦ãã¾ãã
Promise
Promise èªä½ã¯ DOM ããå§ã¾ã£ãä»æ§ã§ããã ECMA ã«ç§»ãã ES6 ã® API ã¨ãªãã¾ããã ããã¾ã§ã¯ onxxxxxx ã¨ããé¢æ°ã«ã³ã¼ã«ããã¯ãç»é²ãããã addEventListener ãç¨ãã API ã主æµã§ããããåçºã®éåæå¦ç㯠Promise ãè¿ã API ã«çµ±ä¸ããã¤ã¤ããã¾ãã
ä¾ãã°åè¿°ã® fetch ã service worker ãªã©ã¯ãã§ã«ãããªã£ã¦ãã¾ãã
Promise ã®ä»æ§ã ES ã®ãã®ã§ããã¡ãªããã¯ã§ããã node/io 㨠browser ã§å®å ¨ã«äºæ㪠API ã§ä½¿ãã¾ãã
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects
Streams
node/io ã§ããªãã¿ã® Stream ã¨åããããªã¤ã¡ã¼ã¸ã§ãã
Stream API ããã©ã¦ã¶ã«ãã£ã¦ãã
ç¹ã«ã¤ãã³ããé£ç¶çã«çºçãã API ã§ã¯ãéä¸ã® chunk ãã¼ã¿ã emit ããããã«ã Promise ã®ä»£ããã« stream ãè¿ã API ã«çµ±ä¸ããã¦ããããã§ãã
node.js ã¨ã¯ãä¾ãã° pipe() ã§ã¯ãªã pipeTo() ã§ãã£ãããå¼æ°ã® API ãéã£ãããã¾ãããåºæ¬çãªèãæ¹ã¯è¿ãã®ã§ãã©ã¡ãã Stream ãã¼ã¹ã§æ¸ããã¨ãã§ããã§ãããã
https://streams.spec.whatwg.org/
ä½ã¬ãã« API ã¨ã®åãåãæ¹
HTML5 ã®ä¸é£ã®æ°è¦ API ç³»ã®è©±ã¯ãå²ã¨ä½¿ãæ¹ã¨ã»ããã§æä¾ããã¦ããããããã¾ãããã ããã«ä¸ãããã㪠API ã¯ãã©ã®ãããªä½¿ãæ¹ããã¦ãæ§ãã¾ããããããããã¥ã¼ããªã¢ã«ã«ãã使ãæ¹ã«éå®ããå¿ è¦ã¯ããã¾ããã
SeviceWorker ã¯ãªãã©ã¤ã³ã ãã®ãããããªããã WebComponents 㯠4 ã¤ã® API ã»ããã§ä½¿ããªãã¨è¡ããªã訳ã§ã¯ãªãã§ãã
ããã¦ãä½ããããããã«ã¯ä½ã¬ãã«ããã¦ä½¿ãã«ããã»ç ©éã ã¨æãããããã¾ããããããã¯å½ç¶ã§ãã ããã¦ä½ã¬ãã«ã¨ãã¦æä¾ããã¦ãããã®ãªã®ã§ããã®ä¸ã§é«ã¬ãã« API ã¨ãã¦ã®ãã¬ã¼ã ã¯ã¼ã¯ãã©ã¤ãã©ãª(ä¾ãã° Polymer ã®ãããª) ãä½ãã使ãã®ãè¯ãã§ããããä»ã¯ã¾ã æã£ã¦ã¯ããªãã®ã§ãéã«èªåãèããæå¼·ã®ã©ã¤ãã©ãªãä½ãã¹ã段éã¨è¨ãã¾ãã
ããã¦ããããã£ã¦ä½ã¬ãã« API ã®ä¸ã«ä½ãããé«ã¬ãã« API ãè¯ããã®ã§ããã°ã jQuery ã querySelector() ã«ç¹ãã£ãããã«æ¨æºåããããåãè¾¼ãã§ãããã¦ãã©ã¦ã¶ã«å®è£ ããã¦ãã©ã¤ãã©ãªç¡ãã§ä½¿ããããã«ãªãå¯è½æ§ãããã¾ãã
è¦ããã«ãæ¨æºåããã©ã¦ã¶ãã³ãã®ãã¨ãªã©ä½ãæ°ã«ããã³ã¼ããæ¸ãã°è¯ããããã Extensible Web ã®ç®æãã¨ããã§ãã
ä¸çªã®åé¡ã¯ãããããä½ã¬ãã« API èªä½ã¯ãæ¨æºåãã¦ãã©ã¦ã¶ãå®è£ ããªãã¨ããã¾ããã ã ãããçæ³ã®ãµã¤ã¯ã«ãåãã«ã¯ããå°ãæéããããã¾ãã
ãã®è¾ºãæè¿èªåãåãçµãã§ããäºãªãã§ãããé·ããªã£ãã®ã§ãã®è©±ã¯ã¾ããããã