美文网首页
cFetch 请求接口的埋点处理

cFetch 请求接口的埋点处理

作者: Allan要做活神仙 | 来源:发表于2017-09-07 14:08 被阅读29次
import fetch from "isomorphic-fetch";
import cookie from "js-cookie";
import StandardError from "standard-error";
import { message } from "antd";
const errorMessages = res => `${res.status} ${res.statusText}`;

/* 资源找不到 */
function check404(res) {
  if (res.status === 404) {
    return Promise.reject(errorMessages(res));
  }
  return res;
}

/* 401是没有登录,跳转到登录页面(根据葛志刚同志要求修改于20170726) */
function check401(res) {
  // 登陆界面不需要做401校验
  if (res.status === 401 && !res.url.match("auth")) {
    // Modal.alert({
    //     title: "登陆验证过期",
    //     content: "您的登陆验证已过期,请重新登陆",
    //     onOk: () => {
    //         cookie.remove('access_token');
    //         window.location.href = '/';
    //     }
    // });
    //
    // return Promise.reject(errorMessages(res));

    window.location.href = window.location.origin + "/#/login";
  }
  return res;
}

function checkStatus(response) {
  const res = response.json();
  if (response.status >= 200 && response.status < 300) {
    return res.then(({ errorCode, errorMsg, result, ...rest }) => {
      if (errorCode) {
        return Promise.reject({
          statusCode: errorCode,
          msg: errorMsg
        });
      }
      return {
        ...rest,
        result
      };
    });
  }

  return res.then(() =>
    Promise.reject({
      statusCode: response.status,
      msg: response.statusText
    })
  );
}

/* 跳转 */
function check302(data) {
  const { errorCode } = data;
  if (errorCode === "302") {
    window.location.href = window.location.origin + "/#/login";
  } else {
    return data;
  }
}

function setUriParam(keys, value, keyPostfix) {
  let keyStr = keys[0];

  keys.slice(1).forEach(key => {
    keyStr += `[${key}]`;
  });

  if (keyPostfix) {
    keyStr += keyPostfix;
  }

  return `${encodeURIComponent(keyStr)}=${encodeURIComponent(value)}`;
}

function getUriParam(keys, object) {
  const array = [];

  if (object instanceof Array) {
    object.forEach(value => {
      array.push(setUriParam(keys, value, "[]"));
    });
  } else if (object instanceof Object) {
    for (const key in object) {
      if (object.hasOwnProperty(key)) {
        const value = object[key];

        array.push(getUriParam(keys.concat(key), value));
      }
    }
  } else {
    if (object !== undefined) {
      array.push(setUriParam(keys, object));
    }
  }

  return array.join("&");
}

function toQueryString(object) {
  const array = [];

  for (const key in object) {
    if (object.hasOwnProperty(key)) {
      const str = getUriParam([key], object[key]);

      if (str !== "") {
        array.push(str);
      }
    }
  }

  return array.join("&");
}

function process(url, options) {
  // let mergeUrl = `${url}?checkSum=${checkSum}`;
  let mergeUrl = `${url}`;
  const defaultOptions = {
    method: "GET",
    credentials: "same-origin"
  };

  let opts = Object.assign({}, defaultOptions, { ...options });

  // add query params to url when method is GET
  if (opts && opts.method === "GET" && opts["params"]) {
    mergeUrl = mergeUrl + "?" + toQueryString(opts["params"]);
  }

  opts.headers = {
    ...opts.headers,
    "X-csrf-token": cookie.get("csrf_token"),
    Authorization: cookie.get("access_token") || ""
  };

  // Authentication
  if (opts.method === "POST") {
    if (Object.prototype.toString.call(opts.body) !== "[object FormData]") {
      opts.body = JSON.stringify(opts.body);
    }
  }
  return { mergeUrl, opts };
}

function cFetch(url, options) {
  const { mergeUrl, opts } = process(url, options);
  // Hack
  // const isPro = window.location.host.indexOf('dingtalk.com') !== -1
  return fetch(mergeUrl, opts)
    .then(check404)
    .then(check401)
    .then(checkStatus)
    .then(check302)
    .catch(err => {
      if (!err.success) message.error( err.msg || "服务器出错");
      // 后面的catch 约定不要弹框,不然就会重复弹框了
      return Promise.reject(err);
    });
}

//catch all the unhandled exception
// window.addEventListener("unhandledrejection", function(err) {
//   const ex = err.reason;
//   if (
//     (ex.constructor !== null && ex.constructor === StandardError) ||
//     ex.msg !== null
//   ) {
//     errorMessages(ex.msg);
//   } else {
//     errorMessages("网络连接失败");
//   }
// });

export default cFetch;

相关文章

  • cFetch 请求接口的埋点处理

  • Hadoop-模拟搭建用户行为日志采集系统分析

    一. kafka应用流程示意 1. 前端js埋点,就是调用后端提供的对应接口.接口请求示例如下: 为了保证轻量级,...

  • 埋点

    埋点分为客户端埋点和服务端埋点。客户端埋点通过restful api请求json数据写入kafka中,可以单条请求...

  • iOS全埋点实践

    客户端埋点大概分为三类: 代码埋点 可视化埋点 无埋点 1、代码埋点 代码埋点,即在需要埋点的节点调用接口直接上传...

  • 责任链模式

    抽象责任链处理者 抽象责任链处理者实现类 请求抽象类或接口 请求抽象类或接口实现类 场景使用

  • vue项目前端埋点

    埋点方案的确定业界的埋点方案主要分为以下三类: 代码埋点:在需要埋点的节点调用接口,携带数据上传。如百度统计等;可...

  • 页面|特定区域内,触底分页加载

    页面: 弹窗类:在需要滚动的地方添加ref或者id 请求分页处理 接口处理

  • vue_axios请求封装、异常拦截统一处理

    1、前端网络请求封装、异常统一处理 vue中采用axios处理网络请求,避免请求接口重复代码,以及各种网络情况造成...

  • Web系统后台行为记录

    关于后台行为记录,可理解为对用户请求的监控日志。也可理解为埋点的一种。通常埋点可简单分为前端埋点和后端埋点。 前端...

  • TableView刷新闪动问题 —— iOS 11

    背景: 商品详情页,内容较多,分多个接口请求加载。根据请求到的数据,来判断是否显示某些内容。 处理方法 多个接口按...

网友评论

      本文标题:cFetch 请求接口的埋点处理

      本文链接:https://www.haomeiwen.com/subject/qudijxtx.html