最近在搞React Native 開發中,發現fetch與之前瀏覽器中使用XMLHttpRequest有一些差異;
XMLHttpRequest方式的用法,相信你們已經很熟悉了,這裏就不介紹了。javascript
先來看看普通的GET的請求:java
// fetch(url,options).then().catch() // url (required), options (optional) fetch('http://nero-zou.com/test', { method: 'GET' }).then(function(response) { }).catch(function(err) { // Error Handle });
fetch會返回一個Promise對象,返回的數據會在response
參數中;git
經過 new Headers()
,你也能夠自由地設置請求頭:github
// 建立一個空的Headers 實例 var headers = new Headers(); // 添加 headers headers.append('Content-Type', 'text/plain'); headers.append('X-My-Custom-Header', 'CustomValue'); // 檢測、獲取、設置 header headers.has('Content-Type'); // true headers.get('Content-Type'); // "text/plain" headers.set('Content-Type', 'application/json'); // 刪除一個 header headers.delete('X-My-Custom-Header'); // 建立時帶上參數 var headers = new Headers({ 'Content-Type': 'text/plain', 'X-My-Custom-Header': 'CustomValue' });
你能夠使用append
, has
, get
, set
, 和delete
去修改request headers. Headers與Request的組合是這樣的:express
var request = new Request('http://ner-zou.com/test', { headers: new Headers({ 'Content-Type': 'text/plain' }) }); fetch(request).then(function() { /* handle response */ });
fetch
返回的 then
方法有一個response
參數,它是一個Response
實例。Response
有以下方法:json
下面看看fetch如何接受服務器端返回的JSON數據:api
fetch('http://nero-zou.com/test.json').then(function(response) { return response.json();// 轉換爲JSON }).then(function(data) { console.log(data); // data 就是一個JavaScript object });
再加上一些錯誤處理:瀏覽器
fetch('http://nero-zou.com/test.json') .then((response) => { if (response.ok) { return response.json() } else { console.error('服務器繁忙,請稍後再試;\r\nCode:' + response.status) } }) .then((data) => { console.log(data) }) .catch((err)=> { console.error(err) })
response.ok
會將40四、500等這些請求錯誤給過濾掉;服務器
官方推薦了一種寫法:網絡
var url = new URL("https://geo.example.org/api"), params = {lat:35.696233, long:139.570431} Object.keys(params).forEach(key => url.searchParams.append(key, params[key])) fetch(url).then(/* … */)
可是URL這個方法,在React Native 中並無實現,那麼就只能咱們本身來拼接url了,
這裏咱們對 GET請求封裝一個方法:
/** * 基於 fetch 封裝的 GET請求 * @param url * @returns {Promise} */ export function R_GET(url, params) { if (params) { let paramsArray = [] Object.keys(params).forEach(key => paramsArray.push(key + '=' + encodeURIComponent(params[key]))) if (url.search(/\?/) === -1) { url += '?' + paramsArray.join('&') } else { url += '&' + paramsArray.join('&') } } return new Promise(function (resolve, reject) { fetch(url) .then((response) => { if (response.ok) { return response.json() } else { reject('服務器繁忙,請稍後再試;\r\nCode:' + response.status) } }) .then((response) => { if (response && response.error_code === 0) { resolve(response)//response.error_code 是與服務器端的約定,非0就是錯誤 } else { reject(response.message)//response.message也是與服務器端的約定,error_code !==0 就須要返回message } }) .catch((err)=> { reject(_parseErrorMsg(err)) }) }) }
在服務器端(Express.js)中能夠這麼接收參數
//假如在客戶端這麼請求的話 //R_GET('http://nero-zou.com/test',{name:nero}) //等同於這樣 fetch('/test?name=nero') //... router.get('/test', function (req, res) { res.send({ error_code: 0, data: {name: req.query.name},//這裏的req.query.name 就是nero了 message: 'success' }); });
客戶端能夠這麼寫:
fetch('http://nero-zou.com/test', { method: 'post', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' //記得加上這行,否則bodyParser.json() 會識別不了 }, body: JSON.stringify({ name: "nero", email: "Nero@Nero-zou.com" }) });
在服務器端(Express.js)中能夠這麼接收數據
//... var bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.json()); //... //... 省略其餘無關代碼 router.post('/test', function (req, res) { res.send({ error_code: 0, data: req.body,//把發過來的數據原封不動返回回去,這裏只是舉例 message: 'success' }); });
fetch('/test', { method: 'POST', headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" }, body: "name=nero&email=Nero@Nero-zou.com" })
一些參考文章: