1. 程式人生 > >Fetch的用法以及資料Mock

Fetch的用法以及資料Mock

fetch是一種可代替 ajax 獲取/提交資料的技術,有些高階瀏覽器已經可以window.fetch使用了。相比於使用 jQuery.ajax 它輕量(只做這一件事),而且它原生支援 promise ,更加符合現在程式設計習慣。

安裝

npm install whatwg-fetch --save,即可安裝,為了相容老版本的瀏覽器,還需要安裝npm install es6-promise --save

fetch的用法

fetch(url,init).then(function(response) {  } )

引數:
url代表要獲取的資源,可能值是一個url或者一個Request物件

init: 可選,是一個物件,引數有

  • method: 請求使用的方法get或者post

  • headers: 請求頭資訊,是一個物件

     headers: {
            "Content-Type": "application/json"
              },
  • body: 請求的 body 資訊:可能是一個 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 物件。注意 GET 或 HEAD 方法的請求不能包含 body 資訊。

  • mode: 請求的模式,如 cors、 no-cors 或者 same-origin,預設為no-cors,該模式允許來自 CDN 的指令碼、其他域的圖片和其他一些跨域資源,但是首先有個前提條件,就是請求的 method 只能是HEAD、GET 或 POST。此外,如果 ServiceWorkers 攔截了這些請求,它不能隨意新增或者修改除這些之外 Header 屬性。第三,JS 不能訪問 Response 物件中的任何屬性,這確保了跨域時 ServiceWorkers 的安全和隱私資訊洩漏問題。cors模式允許跨域請求,same-origin模式對於跨域的請求,將返回一個 error,這樣確保所有的請求遵守同源策略。

  • credentials: ‘include’ //表示跨域是可以帶cookie的(fetch跨域請求預設不會帶cookie,需手動指定這個引數)

  • cache: 請求的 cache 模式: default, no-store, reload, no-cache, force-cache, or only-if-cached.

返回值:一個 Promise,resolve 時回傳 Response 物件。

get的基本使用

首先引入依賴的外掛

import 'whatwg-fetch' 
import 'es6-promise'
var result = fetch('/api/1'
, { credentials: 'include', headers: { 'Accept': 'application/json, text/plain, */*' } });

fetch( )方法請求資料,返回的是一個promise物件,下來就可以使用promise的語法結構

result.then(res=>{
    return res.text()
}).then(text=>{
    console.log(text)
})
result.then(res=>{
    return res.json()
}).then(json=>{
    console.log(json)
})

注意,以上兩個用法中,只有res.text( )和res.json( )是不一樣的,這兩個方法就是將返回的Response 資料轉換成 字串 或者 json格式

post的基本使用

import 'whatwg-fetch' 
import 'es6-promise'

var result = fetch(url,{
    method:'post',
    credentials: 'include',
    headers:{
        'Accept': 'application/json, text/plain, */*', 
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: "a=100&b=200"
})

fetch 提交資料之後,返回的結果也是一個promise物件,跟get方法一樣,所以處理方式也一樣

抽象post和get

如果每次獲取資料,都會像上面一樣寫好多程式碼,太冗餘了。我們可以將get和post分為兩個方法抽象出來,分為兩個js檔案

get.js

import "whatwg-fetch"
import "es6-promise"

export function get(url){
    var result = fetch(url,{
        credentials:"include",
        headers:{
            'Accept':'application/json,text/plain,*/*'
        }
    });

    return result;
}

post.js

import "whatwg-fetch"
import "es6-promise"

// 將物件拼接成 key1=val1&key2=val2&key3=val3 的字串形式

function obj2params(obj){
    var result = "";
    var item;
    for(item in obj){
        result += '&'+ item + '=' + encodeURIComponent(obj[item]);
    }

    //因為result第一個引數是 & 所以需要去掉
    if(result){
        result = result.slice(1);
    }

    return result;
}


// 傳送  請求
export function post(url,paramsObj){
    var result = fetch(url,{
        method:'POST',
        credentials:'include',
        headers:{
            'Accept':'appliaction/json,text/plain,*/*',
            'Content-Type':'application/x-www-form-urlencoded'
        },
        body:obj2params(paramsObj)
    });

    return result;
}

需要注意的是,在post.js中,將引數做了處理,因為上面的程式碼中提到,body: “a=100&b=200”這種引數格式是有要求的,而我們平時在js中,最多用到的就是JSON格式的資料,因此需要轉一下

這兩個方法抽象出來,在從其他元件中呼叫就變的很簡單了

資料Mock

安裝,我們使用的是koa來做後端介面的模擬,因此需要安裝koa以及相關的外掛npm install koa koa-body koa-router --save-dev,注意這裡使用–save-dev,意思是我們只在開發過程中使用 koa ,專案釋出之後 koa 就沒用了。因為釋出之後的專案,使用的就是後端工程師開發的線上的介面,而不是我們基於 koa 寫的介面。

模擬動態介面

即自己用一個 web 框架,按照既定的介面和資料結構的要求,自己模擬後端介面的功能,讓前端專案能順利跑起來。該方式適用於新開發的專案,後端和前端同時開發。

我們將模擬介面的程式碼寫在./mock目錄下,介面檔案是./mock/server.js(開發真正的專案時,會分成多個不同的模組)

注意:在package.json中需要增加如下程式碼,然後npm run mock即可啟動模擬的介面服務

"scripts": { "mock": "node --harmony ./mock/server.js", },

使用webpack-dev-server的代理

koa 介面的埠是3000,而我們專案的介面是8080,這樣不就跨域了嗎?————如果預設情況下,肯定是跨域了。此時就需要 webpack-dev-server 做一個代理的轉發。配置程式碼在./webpack.config.js中

devServer: {
        proxy: {
          // 凡是 `/api` 開頭的 http 請求,都會被代理到 localhost:3000 上,由 koa 提供 mock 資料。
          // koa 程式碼在 ./mock 目錄中,啟動命令為 npm run mock
          '/api': {
            target: 'http://localhost:3000',
            secure: false
          }
        },
        contentBase: "./public", //本地伺服器所載入的頁面所在的目錄
        colors: true, //終端中輸出結果為彩色
        historyApiFallback: true, //不跳轉
        inline: true, //實時重新整理
        hot: true  // 使用熱載入外掛 HotModuleReplacementPlugin
    }