1、基本概述
基于前后端分离的开发模式下,前端通过HTTP请求接口数据是前后端连接的纽带。HTTP协议中规定了GET、POST、PUT、DELETE等请求方式,在通常的业务开发中,最常用的请求方式是GET、POST。被我们熟知的是GET的参数会携带在URL上,POST请求的参数跟随HTTP请求的body传递,关于GET请求和POST的区别,可以自行研究。
在实际开发过程中,HTTP的Header中除了URL、Method、Status等参数外,Content-Type也是经常涉及到的一个参数。使用Content-Type来表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,具体关于Content-Type可以自行研究。
在发起请求时(Request),由于GET请求的参数是携带在URL之后,所以Content-Type对GET请求的影响并不大;对于POST请求,常用的Content-Type有:Form表单格式:application/x-www-form-urlencoded和Json格式:application/json。请求时准确设置Content-Type类型,能够保准后端准确的解释到请求的参数。
前后端分离过程中,势必会涉及到跨域请求,关于跨域请求解决的方法有很多中,常用的是Nginx反向代理。但是对于外部系统的一些接口或者一些公共系统的接口,也经常通过Jsonp的方式请求来解决跨域请求。
针对以上的分析,在基于Umi搭建的Dva脚手架中,针对Umi自带create-umi脚手架生成的代码做相应的更改。分别封装了requestGet、requestPost(默认是Form表单格式的请求)、requestPostJson、requestJsonp的请求方法,在业务场景中可以根据实际情况调用不同的方法,无需在请求的时候去设置对应的请求头。
2、核心代码分析
具体代码在src/lib/request.js中,核心代码如下:
/**
* Requests a URL, returning a promise.
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
function request(url, options, contentType) {
if (contentType === 'json') {
options.headers = {
'Content-Type': 'application/json;charset=UTF-8'
}
}
options = Object.assign({}, defaultOpts, options);
return fetch(url, options)
.then(checkStatus)
.then(parseJSON)
.then((data) => checkResult(url, data))
.catch(err => ({err}));
}
/**
* get请求
* @param url :请求地址
* @param params:请求参数
* @returns 返回Promise对象
*/
export function requestGet(url, params = {}) {
url = stitchUrlParam(url, queryString(params));
return request(url, {method: "GET"})
}
/**
* post请求 ,默认请求 content-Type:form
* @param url :请求地址
* @param params:请求参数
* @param contentType: content-type设置
* @returns 返回Promise对象
*/
export function requestPost(url, params = {}, contentType = 'form') {
if (!contentTypeEnum.includes(contentType)) {
message.error(`请设置正确的请求头【form,json】`, 2);
return;
}
let body = contentType === 'form' ? queryString(params) : JSON.stringify(params);
let options = {
body,
method: 'POST'
}
return request(url, options, contentType)
}
/*post请求,设置content-Type:json */
export function requestPostJson(url, params = {}) {
return requestPost(url, params, 'json')
}
/**
* @param url:请求url
* @param params:请求参数
* @returns 返回Promise对象
*/
export function requestJsonp(url, params) {
url = stitchUrlParam(url, queryString(params));
return fetchJsonp(url)
.then(parseJSON)
.then((data) => data);
}
request方法是对create-umi脚手架生成的方法进行改造,新增contentType字段用于判断是否显示的传入了Content-Type参数,默认设置配置在defaultOpts中。顺便解释一下:checkStatus方法用于检查HTTP请求时,网络状态是否正常;Fetch请求默认返回的是一个Promise对象,parseJSON方法用于将response对象解析成json格式的数据;checkResult方法用于业务接口错误码的处理;
requestGet方法只需将参数拼接在Url后即可,无需其他转换。stitchUrlParam用于确定分隔符是‘?’还是‘&’,queryString方法引用的‘query-string’类库;
requestPost方法,默认contentType = ‘form’,首先判断设置的Content-Type是否合法。然后根据contentType对传入的数据进行处理;如果是Form表单格式,传递的数据形如:key=value;如果是Json格式的,传递的数据格式是:key:value。如果需要通过Json格式发起Post请求,则可以调用requestPostJson,此方法通过调用requestPost方法,并设置contentType 为 ‘Json’;
最后是requestJsonp的封装,通过调用类库’fetch-jsonp’请求实现。
具体的代码链接,请看github链接:https://github.com/zhengchangshun/myUmi/blob/master/src/lib/request.js
上一篇:基于Umi搭建的个人Dva脚手架(一) - 框架说明
下一篇:基于Umi搭建的个人Dva脚手架(三) - 多Layout设计