Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

12. 網路通訊方案

54 views

Published on

探索XMLHttpRequest
封裝XMLHttpRequest
使用Fetch API
認識Server-Sent Events與WebSocket

Published in: Technology
  • Be the first to comment

  • Be the first to like this

12. 網路通訊方案

  1. 1. 12. 網路通訊方案 • 學習目標 – 探索XMLHttpRequest – 封裝XMLHttpRequest – 使用Fetch API – 認識Server-Sent Events與 WebSocket 2
  2. 2. Ajax • 〈Ajax: A New Approach to Web Applications〉 • Asynchronous JavaScript + XML 3
  3. 3. XMLHttpRequest • open(method, url, [asynch, username, password]) • setRequestHeader(header, value) • send(content) • abort() • getAllResponseHeaders() • getResponseHeader(header) 4
  4. 4. readystatechange • XMLHttpRequest.UNSENT • XMLHttpRequest.OPENED • XMLHttpRequest.HEADERS_RECEIVED • XMLHttpRequest.LOADING • XMLHttpRequest.DONE 5
  5. 5. • 多數情況下,只會對readyState為 XMLHttpRequest.DONE時進行處理 6
  6. 6. • responseText預設會使用UTF-8 • 如果回應是XML,伺服端必須指定回應標 頭Content-Type為text/xml • responseXML 7
  7. 7. 8
  8. 8. 9
  9. 9. • 早期XMLHttpRequest並非標準介面 • 就歷史上來說,非同步物件的概念,始於 Microsoft為Exchange Server建立的 Outlook Web Access • 後來被定義為IXMLHTTPRequest介面, 並在MSXML程式庫的第二版中實現 • 1995年的Internet Explorer 5.0搭載了該程 式庫,可透過ActiveXObject,指定 'XMLHTTP'建立實例來存取 10
  10. 10. • Mozilla後來在Gecko樣版引擎仿造了類似 的介面nsIXMLHttpRequest • 而後Mozilla建立了XMLHttpRequest物件, 在2002年Gecko 1.0中獲得了完整實現 • 在Internet Explorer之外的其他主流瀏覽器 上,XMLHttpRequest成了產業標準 • Internet Explorer從2006年的7.0之後,也 開始支援XMLHttpRequest 11
  11. 11. • W3C在2006年開始著手進行 XMLHttpRequest的標準化 • 由於HTML5概念的成形,W3C考慮進化 XMLHttpRequest,在2008年發佈了曾經 被稱為XMLHttpRequest 2或 XMLHttpRequest Level 2的草案 12
  12. 12. • 在2011年時,XMLHttpRequest Level 2草 案被納入了原本的XMLHttpRequest規範 中,成為XMLHttpRequest Level 1 • 曾經的XMLHttpRequest Level 2草案就被 廢棄了 • 現行的XMLHttpRequest規範,可以在 〈XMLHttpRequest〉找到 13
  13. 13. 14
  14. 14. 使用GET請求 • 應用於安全(Safe)操作 – 就規範來說,GET與HEAD(與GET同為取得資 訊,不過僅取得回應標頭)對使用者來說是 「取得」資訊 • 應用於等冪(Idempotent)操作 – 在提供相同的請求資訊下,單一請求產生的結 果,與請求多次的結果必須是相同的 15
  15. 15. • 如果使用傳統表單發送GET請求,GET的請 求參數會出現在網址列 • 然而使用XMLHttpRequest時,GET的請 求參數並不會出現在網址列 16
  16. 16. 17
  17. 17. • 在使用XMLHttpRequest、Fetch API等進 行網路請求時,伺服端採用哪種技術,基 本上與前端無關 • 重點將會擺在伺服端期待收到哪種請求, 瀏覽器又會收到什麼回應 18
  18. 18. 19
  19. 19. 20
  20. 20. 編碼請求參數 • /、?、@、空白等字元,在URL中是保留字 元,RFC 3986規範了保留字元 • 若要在URL表達這些保留字或其他非的 ASCII的字元,必須使用%hexhex編碼形式, 又稱百分比編碼(Percent-Encoding) – url=https://openhome.cc  url=https%3A%2F%2Fopenhome.cc 21
  21. 21. • 可以使用encodeURIComponent()為字 元編碼 • 編碼後的結果是遵循RFC 3986的規範 • HTTP亦規範了GET與POST在發送請求參數 時的編碼 • 基本上與RFC 3986相同,不過空白字元是 編碼為+而不是RFC 3986規範的%20 22
  22. 22. • 若使用encodeURIComponent()編碼, 事後必須將%20取代為+ 23
  23. 23. • JavaScript內部實作上,使用UTF-16碼元 作為字串的元素 • encodeURIComponent()的傳回值,是 將字串處理為UTF-8編碼後,再進行百分 比編碼 • encodeURIComponent()的結果若發送 給伺服端後,伺服端必須以UTF-8來處理 接收到的字串 24
  24. 24. 25
  25. 25. 26
  26. 26. 使用POST請求 • 用於非等冪操作,若請求有副作用,多次 POST請求的結果可以不同 • 為非安全操作,常用來改變伺服端狀態, 運用的場景是新增資料庫的內容、上傳檔 案等 27
  27. 27. • 使用setRequestHeader()設定內容類型 • 因為POST發送的資料不一定是key=value 形式 • 著在呼叫send()時,將發送的資料作為引 數傳入,這是因為POST的資料會放在請求 本體 28
  28. 28. 封裝XMLHttpRequest 29
  29. 29. 30
  30. 30. 31
  31. 31. 32
  32. 32. 上傳檔案 • 在XMLHttpRequest標準化之後可以結合 FormData進行檔案上傳 • 請求標頭Content-Type會自動設為 multipart/form-data 33
  33. 33. • 表單中有type為"file"的input標籤 34
  34. 34. 35
  35. 35. • 如果想實作檔案上傳進度的顯示,是透過 XMLHttpRequestUpload的progress事 件 36
  36. 36. 37
  37. 37. 38
  38. 38. 39
  39. 39. 40
  40. 40. • 若要傳送XML 41
  41. 41. responseXML 42
  42. 42. 43
  43. 43. • 在XMLHttpRequest標準化後,增加了 responseType特性 – 'arraybuffer' – 'blob' – 'document' – 'json' – 'text‘ • 透過response特性取得的對應型態,分別 會是ArrayBuffer、Blob、Document (XML剖析後的結果)、JSON回應剖析後 的物件與字串。 44
  44. 44. 45
  45. 45. 46
  46. 46. 47
  47. 47. 48
  48. 48. 封裝XMLHttpRequest操作 49
  49. 49. 50
  50. 50. 51
  51. 51. 52
  52. 52. 53
  53. 53. 54
  54. 54. 55
  55. 55. 56
  56. 56. 57
  57. 57. 58
  58. 58. Fetch API • fetch()函式只指定網址,預設會發出 GET請求 • 傳回值是Promise,任務達成的結果是個 Response物件 59
  59. 59. • 設定請求資訊 60
  60. 60. • 在method為'GET'或'HEAD'時不能指定 body • fetch()支援跨站請求 • fetch()預設不接受或發送Cookie 61
  61. 61. Request物件 62
  62. 62. • Fetch API會取代XMLHttpRequest? • XMLHttpRequest有豐富的事件類型、必 要時可以設為同步請求、可以中斷請求等 • 在不施加額外的技法或設計時,fetch() 就無法提供逾時、進度處理等功能 63
  63. 63. Server-Sent Events • 模擬伺服端推送 – 輪詢(Polling) – 長輪詢(Long polling) • HTML5規範了Server-Sent Events – 協定 – EventSource • 除了Edge與Internet Explorer之外,現代 瀏覽器都支援EventSource介面 64
  64. 64. • 要包含Content-Type: text/event- stream標頭 • 回應訊息內容時,必須是UTF-8編碼文字 • 格式為field: valuen • 發送一個註解與三個訊息 65
  65. 65. • 預設會觸發的事件為message • 若發生錯誤(像是連線上出了問題)會觸 發error事件 • 可以純綷發出data來觸發message事件 66
  66. 66. • 訊息中若包含id: number,伺服端要送 出回應標頭Last-Event-ID與對應值 number • 若只發送id,表示清除Last-Event-ID 67
  67. 67. • 可以使用event來指定要觸發哪個事件 • 分別觸發add、remove事件: • retry用來指定重新發出連線的時間 68
  68. 68. EventSource • 實例建立後就會發出請求 • 支援跨域請求,然而跨域時預設不發送 Cookie 69
  69. 69. • readyState • 事件 – open – message – error 70
  70. 70. 71
  71. 71. 簡介WebSocket • WebSocket於2011年標準化,在連線建立 之後,客戶端與伺服端可以雙向互動 • 並非基於HTTP,是基於TCP的協定 • 協定昇級機制 • 對前端來說,主要關心的是W3C規範的 The WebSocket API 72
  72. 72. • 如果不考慮IE與Edge,對於僅需要單向接 受伺服端訊息的應用程式來說,使用 Server-Sent Events就足夠了 • 如果客戶端與伺服端需要雙向互動,而不 單只是伺服端推送訊息,例如網路遊戲, 才適合使用WebSocket 73
  73. 73. 74
  74. 74. 75

×