JavaScript 傳送資料
XMLHttpRequest
步驟
- 建立 XMLHTTP 物件
- 建立 callback function 回傳資料更新
- 用 readyState & status 判斷回傳狀態
- 當 return response 時要做的事,通常內容就是 update 畫面上資料
- 向 server 發送資料
- open(‘格式’, ‘網址’, ‘同步與非同步’)
- 非同步 - true
- 等所有資料跑完之後才回傳我們需要的資料
- 為了不讓檔案撈取太慢通常使用這個
- 同步 - false
- 會等資料傳回來才會讓程式往下跑,所以沒跑完值不會顯示
- 非同步 - true
- open(‘格式’, ‘網址’, ‘同步與非同步’)
- 送出資料
- Send the request
1 | // Create XMLHttpRequest |
readyState
- 0: request not initialized
- 已經產生一個 XMLHttpRequest 但是還沒有連接你要的資料
- 1: server connection established
- 用了 open 但資料還沒傳送過去
- 2: request received
- 偵測到用了 send
- 3: processing request
- loding 抓取中
- 4: request finished and response is ready
- 撈到資料了
readyState status from server
- 200,OK(正常)
- 301,Moved Permanently(永久性移動)
- 304,Not Modified(未作修改)
- 307,Temporary Redirect(暫時重新導向)
- 401,Unauthorized(未授權)
- 403,Forbidden(禁止存取)
- 404,Not Found(找不到)
- 500,Internal Server Error(內部伺服器錯誤
onload
- 接資料
- 是當有資料回傳時就自動觸發該函式,而 callback 是有辦法自訂的,兩者不太一樣 onload
- 建立一個 XMLHttpRequest
- 向對方 server 要資料
- 回傳資料內容到自己的瀏覽器
- 處理資料
表單驗證
- 不論是傳送什麼樣的格式或形式(陣列、物件),在用 send 屬性傳送前都必須要先轉 string
- 顯示在 web 上要轉成 object
- 一般表單驗證在 HTML 要加
<form></form>
- form 資料傳送到後端時就會需要使用
- xhr.setRequestHeader(‘Content-type’,’application/x-www-form-urlencoded’);
- JSON 格式
- 透過 AJAX 傳送,不需要加
<form></form>
可以把按鈕格式換成 input - xhr.setRequestHeader(‘Content-type’,’application/json’)
- 透過 AJAX 傳送,不需要加
- get
1 | // 要更後端討論傳到哪個頁面給他做驗證 |
- post
1 | // 建立 xhr 物件 |
- JSON 格式傳送
- json 傳送物件 要轉成 ‘字串’ 傳送
- https://codepen.io/Jimmywei01/pen/ePPOOg
1 | 帳號: |
JSON.stringify(value [, replacer] [, space])
- 將物件(或陣列,甚至是原始型別)序列化為一個 JSON 字串,然後將這個 JSON 字串傳送給 Server 端或 storage
- value
- 要轉換的 JavaScript 值,這個值通常是物件或陣列
- replacer
- 用來轉換結果的函式或陣列
- 如果 replacer 是函式
- 則 JSON.stringify 會呼叫函式,並傳入每個成員的索引鍵和值,並使用傳回值而不是原始值
- 如果函式傳回 undefined,就表示已排除這個成員,根物件的索引鍵是空字串:””
- 如果 replacer 是陣列
- 則只會轉換陣列中有索引鍵值的成員
- 成員的轉換順序與陣列中索引鍵的順序相同。 如果 value 引數也是陣列,則轉換時便會忽略 replacer 陣列
- space
- 加入縮排,空白字元和分行符號字元,讓傳回值 JSON 文字更容易閱讀
- 存到 localStorage
- localStorage.setItem(‘listdata’,JSON.stringify(data))
1 | const someObj = { |
JSON.parse(text [, reviver])
- 將 JSON 字串剖析為 JavaScript 物件
- text
- 有效的 JSON 字串
- reviver
- 用來轉換結果的函式,呼叫這個函式時,會針對這個物件的每個成員進行呼叫
- 如果成員包含巢狀物件,則會先轉換巢狀物件,然後再轉換父物件
- 就個別成員而言,發生的情況如下:
- 如果 reviver 傳回有效值,轉換後的值會取代成員值
- 如果 reviver 的傳回值與它接收的值相同,則不會修改成員值
- 如果 reviver 傳回 null 或 undefined,表示成員已刪除
- 轉到 Web 顯示
- JSON.parse(localStorage.getItem(‘listdata’))
1 | var jsonStr = '{"name": "Summer"}'; |
jQuery
- http://api.jquery.com/jquery.ajax/
- https://www.jianshu.com/p/bb686b367800
- https://www.css88.com/jqapi-1.9/jQuery.ajax/
注意
- dataType:“json” 在 radio 無法起作用
- https://codepen.io/Jimmywei01/pen/qJeyLZ?editors=1011
語法
- 解決的不只是簡化語法或解決不同瀏覽器之間問題而已
- 擴充了原有 XHR 並加入類似 Promise 的設計
1 | var postData = { "param1" : "param1", "areaId" : 2, "deleteId" : 3 }; |
語法簡寫
- 預設方法是 GET
- then 預防 callback 地獄 (promise 概念)
1 | $.ajax( API 網址).then(function(res){…..執行動作(e.g. 更新網⾴)}) |
Method
- 常見方法對應場景
- get 取得
- post 新增
- put 更新
- delete 刪除
- [GET] /post 取得所有⽂章
- [GET] /post/:id 取得單篇⽂章
- [POST] /post 儲存新⽂章
- [PUT] /post/:id 更新單篇⽂章
- [DELETE] /post/:id 更新單篇⽂章
非同步設定
- 預設 async: false
1 | $.ajax({ |
.done()表示
- 有 Deferred.done() 方法接受一個或多個參數,所有這些都參數可以是一個單一的函數或一個函數數組,當 deferred(延遲)解決時,依照添加的順序執行doneCallbacks
- $.ajax()如果執行成功,則執行 .done(),funtion(e) 中的 e 為返回結果
- $.ajax()執行發生錯誤,則 .done()不執行
1 | function getArticleList(callback){ |
Fetch
- https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
- fetch(input[, init])
- 使用 fecth 的時候它會先回傳 Promise 給我們,再回傳第一個參數 readableStream,需要先把它解析成 json 來讀取,在 then 中 return 的內容會到下一個 then 的 callback 中可以使用
- 第二個參數是選用的,可以傳送一個 init Object 來設定 request
- 與 $.ajax 不同點
- 默認情況下,fetch 不會從 server 發送或接收任何 cookie ,如果依賴於用戶 session,則會導致未經認證的請求(要發送 cookies,必須設置 credentials 選項)
- then 作為下一步
- catch 作為錯誤回應 (404, 500…)
- 回傳的為 ReadableStream 物件,需要使用不同資料類型使用對應方法,才能正確取得資料物件
1 | fetch('https://randomuser.me/api/', {}) |
- ReadableStream
- Response 物件中的 body 屬性提供了一個 ReadableStream 的實體
- ReadableStream 物件中可用以下對應的方法來取得資料(轉換資料)
- arrayBuffer()
- blob() — 物件
- formData() — 上傳文件
- json()
- text() — 字串
- URL 是新的 API,可以將 blob 物件轉為網址
1 | // unsplash 上的圖片 |
- 傳送 JSON 格式到 server
1 | var url = 'https://example.com/profile'; |
JSONP
使用時機
- 用
<script type="text/javascript">
進行跨域請求(因為他沒有限制)
使用方式
- 可以給整體數據添加一個變量名,在
<script>
中用參數傳遞(但這會有整體設計問題)
1 | // hello.txt |
- 動態創建
<script>
- 通過函數調用,給函數傳遞參數的方式將整體數據傳遞過去
- A 在資源加載之前定義一個後台定義的函數,在函數中接收一個參數,在函數中即是獲取數據後的操作
- A 的 function 要跟 B 調用的名子一樣
- B,需要時通過後台定義的函數加載對應的數據,當數據加載進來的後,就會調用前面定義好的函數,並且將數據當做上函數的參數傳入
1 | // html |
JSONP 使用方式以環保署 api 為例
jQuery 封装 JSONP
- jsonp: ‘callback’ 為要和伺服器端進行溝通,這個請求傳送到伺服器端,實際上這樣的
- 伺服器端需要通過 callback 來取值也就是取後面的 jqueryxxxx 等自動生成的值,這個值實際上就是對應的我們傳送請求的 ajax 方法中的 success ,假設伺服器端如果返回
- jqueryxxxx({“ret”:”ok”})
- 頁面中會自動執行 success 方法,且將 {“ret”:”ok”} 傳給 success方法的引數 result
1 | // 1.定義函數(得到數據後的操作) |
$.getJSON()
1 | <script type="text/javascript"> |