zoukankan      html  css  js  c++  java
  • fetch的使用--当无法判断后台返回数据为什么类型时如何操作

    需求:一个增删改查页面,当新增,删除或者修改操作时不确定后台会返回的信息(会根据需求不同请求成功后可能返回message,可能什么都不返回)

    问题:使用fetch进行请求时, Fetch API 的 Response 接口呈现了对一次请求的响应数据,response解析数据的方法我用到的为response.json()和response.text(),因为response可以获取到状态码,请求状态,但是在解析之前是不清楚返回到结果用哪种方式解析的,如果后台返回的为空还用json的方式就会报错   "Unexpected end of JSON input"

    解决:

    在fetch请求后使用了三个then去处理各种状态的返回值:

      1)第一个then判断是否请求成功,失败则直接返回错误信息

      2)成功则在第二个then中判断mothed类型,若为增删改状态则返回response.text(),其他类型返回response.json()

      3)第三个then接收第二个then的返回值,若mothed类型为增删改则判断后台是否返回了message,返回则进行解析并渲染出返回值,若无返回值则不进行操作,其他类型则直接返回第二个then中的返回值


    const checkStatus = response => {
     //当请求成功时直接返回response,失败则进行json解析返回失败信息
    if (response.status == 200) { return response }else{ return response.json().then(json => { return Promise.reject(json) }) } };
    export default function basicRequest(url, option) {
      const options = {
      expirys: isAntdPro(),
        ...option,
      };
      const fingerprint = url + (options.body ? JSON.stringify(options.body) : '');
      const hashcode = hash
        .sha256()
        .update(fingerprint)
        .digest('hex');

      const defaultOptions = {
        credentials: 'include',
      };
      const newOptions = { ...defaultOptions, ...options };

      if (
        newOptions.method === 'POST' ||
        newOptions.method === 'PUT' ||
        newOptions.method === 'DELETE' ||
        newOptions.method === 'PATCH'
      ) {
        if (!(newOptions.body instanceof FormData)) {
          newOptions.headers = {
            Accept: 'application/json',
            'Content-Type': 'application/json; charset=utf-8',
            ...newOptions.headers,
          };
          newOptions.body = JSON.stringify(newOptions.body);
        } else {
          newOptions.headers = {
            Accept: 'application/json',
            ...newOptions.headers,
          };
        }
      }

      const expirys = options.expirys && 60;
      if (options.expirys !== false) {
        const cached = sessionStorage.getItem(hashcode);
        const whenCached = sessionStorage.getItem(`${hashcode}:timestamp`);
        if (cached !== null && whenCached !== null) {
          const age = (Date.now() - whenCached) / 1000;
          if (age < expirys) {
            const response = new Response(new Blob([cached]));
            return response.json();
          }
          sessionStorage.removeItem(hashcode);
          sessionStorage.removeItem(`${hashcode}:timestamp`);
        }
      }
    return fetch(url, newOptions)
        .then(checkStatus)
        .then(response => {
        //请求成功状态下,method正常情况使用response.json()将结果返回,当进行增删改时使用response.text(),在返回值为空或者有返回值是text()都不会报错
    if (newOptions.method === 'DELETE'|| newOptions.method === 'POST'|| newOptions.method === 'PATCH'|| newOptions.method === 'PUT') { return response.text(); } return response.json(); }).then(e=>{
        //获取上一步返回的值,当method非增删改状态直接返回值,反之判断返回值是否存在,若存在解析一下弹出信息,若不存在不做操作
    if (newOptions.method === 'DELETE'|| newOptions.method === 'POST'|| newOptions.method === 'PATCH'|| newOptions.method === 'PUT') { if(e){ const msg = JSON.parse(e) if(msg.message){ notification.success({ message: msg.message }) } } } return e }) .catch(e => {//获取错误信息并弹出 notification.error({ message: e.message }) })
    }

    首发于 博客园

  • 相关阅读:
    vue学习6
    vue学习5
    vue学习3
    vue学习2
    vue学习1
    idea快速查找和替换快捷键
    mysql三元表达式
    1 Java Lambda表达式forEach无法跳出循环的解决思路
    6 Mybatis Plus and 和 or,分页Page使用
    4 Mybatis Plus使用redis作为二级缓存
  • 原文地址:https://www.cnblogs.com/yunyea/p/10827072.html
Copyright © 2011-2022 走看看