基于Umi搭建的个人Dva脚手架(二) - HTTP请求的封装

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设计


dva中,我们可以通过封装request方法来对http请求进行进一步的封装,使其更加方便和易用。 一种常见的做法是封装一个request工具函数,该函数会返回一个Promise对象,我们可以在models中的effect中使用该函数来发送网络请求。该函数可以包含一些自定义的配置参数,例如请求method、请求头、请求体等。 以下是一个基于dvahttp请求封装示例代码: ```javascript import request from 'umi-request'; function http(url, options) { return request(url, options) .then(response => { if (response && response.status === 200) { return response.data; } else { throw new Error('请求失败'); } }) .catch(error => { console.error(error); throw error; }); } export default http; ``` 在上面的代码中,我们封装了一个http函数,该函数接收两个参数,分别为url和options。这两个参数与request函数的参数一致。我们使用request函数发送网络请求,并在then方法中判断请求是否成功。如果成功,我们会将请求结果返回;如果失败,我们会抛出一个错误。 在使用http函数时,我们可以通过传入options参数来自定义请求配置,例如: ```javascript http('/api/data', { method: 'post', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ name: 'test', age: 20 }) }) .then(data => { console.log(data); }) .catch(error => { console.error(error); }); ``` 在上面的代码中,我们通过传入options参数来自定义请求的method、headers和body。如果请求成功,我们会在then方法中打印请求结果;如果请求失败,我们会在catch方法中打印错误信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值