react中請求介面的封裝
1. 新建一個dva專案。使用antd 或者antd-mobile元件庫。
$ npm install dva-cli -g $ dva -v $ dva new dva-quickstart $ npm start
$ npm install antd babel-plugin-import --save 或者是 $ npm install antd-mobile babel-plugin-import --save
匯入方式css
{ "entry": "src/index.js", "env": { "development": { "extraBabelPlugins": [ "dva-hmr", "transform-runtime", ["import", { "libraryName": "antd-mobile", "style": "css" }] ] }, "production": { "extraBabelPlugins": [ "transform-runtime", ["import", { "libraryName": "antd-mobile", "style": "css" }] ] } } }
2. 在該專案的src中utils 建立名為request資料夾。
$ cd dva-quickstart $ cd src $ cd utils
新建資料夾名為request,然後在request資料夾下面建立名為helpers的資料夾以及index.js 和 README.md , request.js 如圖所示:
在helpers 下建三個js檔案 combineURL.js , isAbsoluteURL.js , serialize.js
image.png
combineURL.js中 :
// Creates a new URL by combining the specified URLs
const combineURL = (baseUrl, path) => {
return `${baseUrl.replace(//+$/, '')}/${path.replace(/^/+/, '')}`;
};
export default combineURL;
combineURL.js中 :
// Creates a new URL by combining the specified URLsconst combineURL = (baseUrl, path) => { return `${baseUrl.replace(//+$/, '')}/${path.replace(/^/+/, '')}`; };export default combineURL;
isAbsoluteURL.js中 :
// A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL).// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed// by any combination of letters, digits, plus, period, or hyphen.// isAbsoluteURL = (url) => /^([a-z][a-zd+-.]*:)?///i.test(url);export default isAbsoluteURL;
serialize.js中 :
import { isPresent } from 'lib/lang';const encode = (value) => { return encodeURIComponent(value) .replace(/%40/gi, '@') .replace(/%3A/gi, ':') .replace(/%24/g, '$') .replace(/%2C/gi, ',') .replace(/%20/g, '+') .replace(/%5B/gi, '[') .replace(/%5D/gi, ']'); };// Encode a set of form elements as a string for submission.const serialize = (params) => { const ret = []; Object.keys(params).forEach(key => { const value = params[key]; if (isPresent(value)) { ret.push(`${encode(key)}=${encode(value)}`); } }); return ret.join('&'); };export default serialize;
3. 在utils下建立一個與request同級的lang.js
lang.js 如下:
export const isPresent = (obj) => { return typeof obj !== 'undefined' && obj !== null; };export const isBlank = (obj) => { return typeof obj === 'undefined' || obj === null; };export const isBoolean = (obj) => { return typeof obj === 'boolean'; };export const isNumber = (obj) => { return typeof obj === 'number'; };export const isString = (obj) => { return typeof obj === 'string'; };export const isArray = (obj) => { return Array.isArray(obj) || Object.prototype.toString.call(obj) === '[object Array]'; };export const isDate = (obj) => { return obj instanceof Date && !isNaN(obj.valueOf()); };export const isFunction = (obj) => { return typeof obj === 'function'; };export const isJsObject = (obj) => { return obj !== null && (isFunction(obj) || typeof obj === 'object'); };export const isPromise = (obj) => { return isPresent(obj) && isFunction(obj.then); };export const isEmpty = (obj) => { if (isBlank(obj)) { return true; } if (obj.length === 0) { return true; } for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { return false; } } return true; };export const normalizeBlank = (obj) => { return isBlank(obj) ? null : obj; };export const normalizeBool = (obj) => { return isBlank(obj) ? false : obj; };export const stringify = (token) => { if (isString(token)) { return token; } if (isBlank(token)) { return String(token); } const ret = token.toString(); const newLineIndex = ret.indexOf('n'); return (newLineIndex === -1) ? ret : ret.substring(0, newLineIndex); };export class PromiseWrapper { // Excutes promises one by one, e.g. // const promise = () => new Promise(...) // const promise2 = () => new Promise(...) // sequentialize([ promise, promise2 ]) static sequentialize = promiseFactories => { let chain = Promise.resolve(); promiseFactories.forEach(factory => { chain = chain.then(factory); }); return chain; } // Promise finally util similar to Q.finally // e.g. finally(promise.then(...)) /* eslint-disable consistent-return */ static finally = (promise, cb) => promise.then(res => { const otherPromise = cb(); if (typeof otherPromise.then === 'function') { return otherPromise.then(() => res); } }, reason => { const otherPromise = cb(); if (typeof otherPromise.then === 'function') { return otherPromise.then(() => { throw reason; }); } throw reason; }) }/* eslint-enable consistent-return */export class StringWrapper { static equals = (s1, s2) => s1 === s2; static contains = (s, substr) => s.indexOf(substr) !== -1; static compare = (a, b) => { if (a b) { return 1; } return 0; } }/* eslint-disable max-params */export class DateWrapper { static create( year, month = 1, day = 1, hour = 0, minutes = 0, seconds = 0, milliseconds = 0 ) { return new Date(year, month - 1, day, hour, minutes, seconds, milliseconds); } static fromISOString(str) { return new Date(str); } static fromMillis(ms) { return new Date(ms); } static toMillis(date) { return date.getTime(); } static now() { return Date.now() || new Date(); } static toJson(date) { return date.toJSON(); } }/* eslint-enable max-params */
這個是dva自動生成的request.js 把這個檔案換下名字requests.js,它與lang.js同級。
4. 開啟在request檔案下request.js,進行編輯:
request.js
import fetch from 'dva/fetch';import { isEmpty } from '../lang';import serialize from './helpers/serialize';import combineURL from './helpers/combineURL';import isAbsoluteURL from './helpers/isAbsoluteURL';import { apiBaseUrl } from '../../config';import { Toast } from 'antd-mobile';const wait = ms => new Promise(resolve => setTimeout(resolve, ms));const timeout = (p, ms = 30 * 1000) => Promise.race([ p, wait(ms).then(() => { const error = new Error(`Connection timed out after ${ms} ms`); error.statusCode = 408; throw error; }), ]);// Request factoryfunction request(url, options, method) { const { endpoint, ...rest } = interceptRequest(url, options, method); const xhr = fetch(endpoint, rest).then(interceptResponse); return timeout(xhr, request.defaults.timeout).catch((error) => { // return Promise.reject(error); }); } request.defaults = { baseURL: apiBaseUrl, timeout: 10 * 5000, headers: { Accept: 'application/json', }, };// Headers factoryconst createHeaders = () => { const headers = { ...request.defaults.headers, }; // const auth = JSON.parse(localStorage.getItem('auth'+sessionStorage.getItem("hid"))); // const token = sessionStorage.getItem('token'); //登入location獲取到的token存放l // if (auth) { // // Toast.info(`請稍等: ${token}`, 2); // // Toast.loading(''); // headers.Authorization = auth.Token; // } else if (token) { // // ; // // Toast.info(`請稍等: ${token}`, 2); // // Toast.loading(''); // headers.Authorization = token; // } headers.Authorization = "app"; return headers; };// Request interceptorfunction interceptRequest(url, options, method) { let endpoint; if (isAbsoluteURL(url)) { endpoint = url; } else { endpoint = combineURL(request.defaults.baseURL, url); } let data = { method, endpoint, headers: createHeaders(), }; if (!isEmpty(options)) { data = { ...data, ...options, }; if (options.json) { data.headers['Content-Type'] = 'application/json;charset=utf-8'; data.body = JSON.stringify(options.json); } if (options.form) { data.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; data.body = serialize(options.form); } if (options.body) { data.body = options.body; const auth = JSON.parse(localStorage.getItem('auth'+sessionStorage.getItem("hid"))); if (auth) { if (auth && options.body instanceof FormData && !options.body.hasPatientid) { // options.body.append('patientid', auth.Patientid); } } } if (options.params) { endpoint += `?${serialize(options.params)}`; data.endpoint = endpoint; } } return data; }// Response interceptor/* eslint-disable consistent-return */function interceptResponse(response) { return new Promise((resolve, reject) => { const emptyCodes = [204, 205]; // Don't attempt to parse 204 & 205 if (emptyCodes.indexOf(response.status) !== -1) { return resolve(response.ok); } if (response.ok) { const contentType = response.headers.get('Content-Type'); if (contentType.includes('application/json')) { resolve(response.json()); } resolve(response); } if (response.status === 401) { // return Toast.fail('認證資訊已過期,請重新登入', 2, () => { // return Toast.fail('請重新登入', 2, () => { localStorage.removeItem('auth'+sessionStorage.getItem("hid")); // sessionStorage.removeItem('token'); location.reload(); // TODO:跳轉登入路由 // }); } const error = new Error(response.statusText); try { response.clone().json().then((result) => { error.body = result; error.response = response; reject(error); }); } catch (e) { error.response = response; reject(error); } }); }/* eslint-enable consistent-return */// sugerrequest.get = (url, options) => request(url, options, 'GET'); request.head = (url, options) => request(url, options, 'HEAD'); request.options = (url, options) => request(url, options, 'OPTIONS'); request.post = (url, options) => request(url, options, 'POST'); request.put = (url, options) => request(url, options, 'PUT'); request.delete = (url, options) => request(url, options, 'DELETE'); request.del = request.delete;export default request;
5. 這樣你就可以在今後的專案正常使用按照以下步驟
module.exports = { apiBaseUrl: "", };
之後再services檔案下就可以這樣去下啦:
import request from '../utils/request/request';export function queryScaleMenu(start, limit) { const body = new FormData(); body.append('start',start); body.append('limit', limit); return request.post('news/menu/query', { body }); }
作者:sidney_c
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/854/viewspace-2814447/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- vue中axios請求的封裝VueiOS封裝
- 封裝axios請求封裝iOS
- 封裝ajax、axios請求封裝iOS
- axios 請求資料封裝iOS封裝
- OC:封裝網路請求封裝
- Kotlin中Retrofit網路請求簡單封裝Kotlin封裝
- Vue 封裝axios(四種請求)及相關介紹(十三)Vue封裝iOS
- 基於 Fetch 的請求封裝封裝
- 釘釘小程式 請求封裝封裝
- go對get、post請求封裝Go封裝
- 小程式-網路請求封裝封裝
- Flutter 網路請求 Dio 封裝Flutter封裝
- 十. Axios網路請求封裝iOS封裝
- fetch資料請求的封裝封裝
- Flutter 網路請求框架封裝Flutter框架封裝
- 基於jq封裝ajax請求封裝
- urllib.request.Request物件封裝請求物件封裝
- 封裝 Laravel 自定義表單請求封裝Laravel
- iris 系列文章 封裝 請求日誌封裝
- 命令模式-將請求封裝成物件模式封裝物件
- 微信小程式 request請求封裝微信小程式封裝
- js ajax請求封裝及解決node請求跨域問題JS封裝跨域
- 封裝 uniapp 請求庫的最佳實踐封裝APP
- Vue — 請求模組、api模組封裝VueAPI封裝
- [譯]axios 是如何封裝 HTTP 請求的iOS封裝HTTP
- flutter dio網路請求封裝實現Flutter封裝
- 封裝springmvc處理ajax請求結果封裝SpringMVC
- uni-app網路請求的封裝APP封裝
- 微信小程式request請求的封裝微信小程式封裝
- 基於小程式請求介面 wx.request 封裝的類 axios 請求封裝iOS
- 基於FutureBuilder通用網路請求介面封裝Rebuild封裝
- Vue功能篇 - 3.封裝axios請求庫Vue封裝iOS
- .Net Standard HttpClient封裝Htt請求常用操作整理HTTPclient封裝
- 用原生js封裝一個ajax請求方法JS封裝
- python-對requests請求簡單的封裝Python封裝
- vue介面請求方式axios二次封裝VueiOS封裝
- 對api請求封裝的探索和總結API封裝
- 在 React Hooks 中如何請求資料?ReactHook