XHR (XML HttpRequest), FETCH

在前端發 ajax 只有兩種發法

fetch 會回傳 promise,一種物件類型

其他的 function 或瀏覽器內建函式也可能會回傳 promise

fetch 回傳 promise 物件
response.text() 也是回傳 promise 物件

.then() 裡面要放一個 function

<script>
    function printResult(a) {
      console.log(a)
    }
    const result = fetch('https://run.mocky.io/v3/a8f29e65-d81e-4c8c-9982-ea4d46115acf')
    result.then(printResult)
  </script>

簡化

<script>
    const END_POINT = 'https://run.mocky.io/v3/a8f29e65-d81e-4c8c-9982-ea4d46115acf'
    fetch(END_POINT)
      .then(response => console.log(response.status))
  </script>

再改寫

<script>
    const api500 = 'https://run.mocky.io/v3/7b8f483c-dd45-42c1-a745-f0a622ed1c6a'
    const api200 = 'https://run.mocky.io/v3/c7a74184-01b8-48c1-8714-1206ccc77c51'
    fetch(api200)
      .then(response => response.json())
      .then(json => console.log(json)) // {text: "text"}
  </script>

結果:


response.text().then()

可以拿到 body 的資料而不是 promise 格式

fetch 錯誤處理與 POST

對於 fetch 來說連 response 都拿不到才算 fail

<script>
    const api500 = 'https://run.mocky.io/v3/7b8f483c-dd45-42c1-a745-f0a622ed1c6a'
    const api200 = 'https://run.mocky.io/v3/c7a74184-01b8-48c1-8714-1206ccc77c51'
    const data = {
      name: 'yo'
    }
    fetch(api200, {
      method: 'POST',
      body: JSON.stringify(data),
      headers: new Headers ({
        'Content-type': 'applicaiton/json',
      })
    })
      .then(response => response.json())
      .then(json => console.log(json))
      .catch(error => console.log(error))
  </script>


FETCH 的注意事項

content-type

若 content-type 與 body 的格式不符,server 會出錯。
看 server 接收什麼格式的資料,決定 content-type

credentails

當發 cross-orgin 的 request 時,需要有 crednetials( 憑據),需要傳 cookies 要設定

credentials: 'inclue'

mode

mode: 'no-cors'

設定以上參數的原因:是知道 server 沒有提供 CORS 的 header,但依舊要發 request,不用回傳關於 CORS 的錯誤訊息給 client 端。

不可能 client 端突破 CORS 的限制。

<script>
    const api500 = 'https://run.mocky.io/v3/7b8f483c-dd45-42c1-a745-f0a622ed1c6a'
    const api200 = 'https://run.mocky.io/v3/c7a74184-01b8-48c1-8714-1206ccc77c51'
    const lidemy = 'https://lidemy.com'
    const data = {
      name: 'yo'
    }
    fetch(lidemy, {
      method: 'POST',
      body: JSON.stringify(data),
      headers: new Headers ({
        'Content-type': 'applicaiton/json',
      }),
      credentials: 'include',
      mode: 'no-cors',
    })
      .then(response => response.json())
      .then(json => console.log(json))
      .catch(error => console.log(error))
  </script>



#程式導師實驗計畫第四期 #前端 #fetch







Related Posts

[進階 js 08] Closure

[進階 js 08] Closure

從 React 原始碼看 keyPress 與 keyDown 事件

從 React 原始碼看 keyPress 與 keyDown 事件

原子習慣:進階策略 - 如何從「A」到「A+」

原子習慣:進階策略 - 如何從「A」到「A+」


Comments