V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
xjdata
V2EX  ›  问与答

请问使用 fetch api 库请求 的结果重新包装一下?

  •  
  •   xjdata · 2016-10-11 08:12:40 +08:00 · 5382 次点击
    这是一个创建于 2994 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家好, 我使用这个库https://github.com/dvajs/dva/blob/master/fetch.js请求 yii2 的 rest api 时, 如何才能将服务器返回的头部x-pagination-page-count, x-pagination-total-count等信息包装进返回结果呢?

    当前 api 返回信息的头部已包含下列信息

    x-pagination-current-page:1
    x-pagination-page-count:35
    x-pagination-per-page:12
    x-pagination-total-count:411
    

    我希望将返回的的 data 重新包装下,使 data 对象包含 list(原来的返回结果), 服务器头信息的 x-pagination-total-count,x-pagination-page-count.等信息

    但是现在 我只能获取到, 纯粹的 rest 返回结果 是个数组. 我尝试在 request 类中重新封装数据, 各种尝试都失败了. 各种搜 可能是关键词不对 也没有找到解决办法.

    请问各位大神, 如何 才能包装成我需要的 对象呢? 谢谢!!!

    请求代码如下:

     const {data} = yield call(query, parse(payload));
          if (data) {
            console.log(data); //!!!这里!!!  我希望将这里返回的 data 重新包装下,使 data 对象 list, 服务器头信息,x-pagination-total-count,x-pagination-page-count.等信息 
            // 但是现在 我只能获取到, 纯粹的 rest 返回结果 是个数组. 我尝试在 request 类中重新封装数据, 各种尝试都失败了. 各种搜  可能是关键词不对  也没有找到解决办法. 
            yield put({
              type: 'querySuccess',
              payload: {
                list: data.list,
                total: Number(data.total),
                current: Number(data.current),
                pageSize: data.pageSize ? data.pageSize : 12,
              }
            });
          }
    

    异步方法如下:

    export async function query(params) {
      return request(`/api/users?${qs.stringify(params)}`);
    }
    

    request 类 如下:

    import fetch from 'dva/fetch';
    
    function checkStatus(response) {
      if (response.status >= 200 && response.status < 300) {
        //这里是可以读取到这些信息的. 但是我不会重新包装. 
        console.log(response.headers.get('x-pagination-page-count')); //35
        console.log(response.headers.get('x-pagination-total-count')); //411
        return response;
      }
      const error = new Error(response.statusText);
      error.response = response;
      throw error;
    }
    
    function parseJSON(response) {
    
      return response.json();
    }
    /**
     * 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"
     */
    export default function request(url, options) {
      return fetch(url, options)
        .then(checkStatus)
        .then(parseJSON)
        .then((data)=>({data}))
        .catch((err) => ({ err }));
    }
    
    

    yii2 的 rest controller 如下:

    <?php
    namespace api\modules\test\controllers;
    
    use yii;
    use yii\helpers\ArrayHelper;
    class UsersController extends yii\rest\ActiveController
    {
        public $modelClass = '\common\models\User';
        public function behaviors() {
            return ArrayHelper::merge(parent::behaviors(), [
                'corsFilter' => [
                    'class' => \yii\filters\Cors::className(),
                    'cors' => [
                        // restrict access to
                        'Origin' => ['*'],
                        'Access-Control-Request-Method' => ['*'],
                        'Access-Control-Request-Headers' => ['*'],
                        'Access-Control-Allow-Credentials' => true,
                        // Allow OPTIONS caching
                        'Access-Control-Max-Age' => 3600,
                        // Allow the X-Pagination-Current-Page header to be exposed to the browser.
                        'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
                    ],
                ],
            ]);
        }
    
        public function actions()
        {
            $actions = parent::actions();
            // 禁用"delete" 和 "create" 操作
            unset($actions['delete'], $actions['create']);
            return $actions;
        }
    }
    
    7 条回复    2016-10-11 17:31:46 +08:00
    Septembers
        1
    Septembers  
       2016-10-11 08:36:27 +08:00   ❤️ 1
    .then(response => ({data: response.json(), headers: response.headers}))
    AdamChrist
        2
    AdamChrist  
       2016-10-11 08:36:52 +08:00   ❤️ 1
    我也用 dva,里面的 fetch 用的是 isomorphic-fetch.可以去看下 API

    在转 jason 的时候把头信息一起整合一下返回去..
    可以把 response.json() 改成 response.json().then(result=>{return {pageCount :response.header.xxx,...result}})
    jianguiqubaa
        3
    jianguiqubaa  
       2016-10-11 09:13:15 +08:00   ❤️ 1
    一楼正解
    coldsnap
        4
    coldsnap  
       2016-10-11 10:28:42 +08:00   ❤️ 1
    parseJSON() 那个函数写成一楼的样子就可以了
    xjdata
        5
    xjdata  
    OP
       2016-10-11 14:43:24 +08:00
    多谢各位!! 真是不会难死人.

    我确实已经在封装部分考虑下手了. 但是, 哎!!!! promise 的这种写法太懵懵懂懂. 根本不知道怎么下手....

    谢谢.
    xjdata
        6
    xjdata  
    OP
       2016-10-11 14:48:34 +08:00
    @AdamChrist 请问一点 dva 的实际开发经验. 部门列表, 等等可以缓存的数据 及 这些数据产生的组件. 要如何进行开发和管理呢?

    比如有个树列表. 根据这个树 开发了 一个下拉菜单, 一个数控件 (我都用的 antd)
    1. 他们的数据是分别建立 model 呢? 还是共用?
    2. 这些数据可以缓存吗? (我服务器端已经缓存,但是客户端希望也能缓存,直接不在去请求服务器)
    3. 这些控件 如果封装的好, 应该可以在不同的场景中直接复用吧?
    AdamChrist
        7
    AdamChrist  
       2016-10-11 17:31:46 +08:00
    1.图省事的话在就在每个不同的 Modal 中初始化.但是在树和下来菜单的需要的数据结构可能不同.在传入组件之前要做下整理.如果总是用到的话..可以弄到公用的 Modal 中.
    2.放到 redux 中就是已经算是缓存了.
    3.是的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2144 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:08 · PVG 00:08 · LAX 08:08 · JFK 11:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.