JS - 使用Fetch API获取文本或JSON

时间:2016-09-03 17:11:30

标签: javascript fetch-api

我正在从jQuery AJAX请求转移到新的Fetch API(没有反对jQuery,我仍然在我的网站中,但Fetch看起来 - 根据Jake ArchibaldDavid Walsh以及恕我直言 - 成为发送异步请求的新方法。

因此,使用jQuery,我有以下功能(或多或少):

function ajaxCall(type, url, data) {
  return $.ajax({
    type: type,
    url: url,
    data: data,
  })
  .fail(function(xhr, status, errorThrown) {
    // Do fail stuff
  })
  .always(function(xhr, status) {
    // Do always stuff
  });
}

// Later...
var myAjax = ajaxCall(myType, myUrl, myData);
myAjax.done(function(xhr) {
 // Do done stuff
});

这样,我可以调用一个函数来处理任何所有 ajax请求我可能需要(至少在大多数情况下......)。请注意,我没有声明dataType,因为我使用了jQuery' s intelligent guess。这样我的服务器可以向我发送任何响应,我可以处理它(可能更聪明的方法是传递另一个带有数据类型的参数 - 如果"智能猜测"出错了,但是这是我设置它的方式。)

我现在正尝试使用新的Fetch API重新创建上述内容。到目前为止,我目前看起来像这样:

function fetchCall(url, method, body) {
  // This if statement is supposed to handle
  // query selectors (which in GET requests go in the url)
  // on GET requests - as opposed to POST req's which go in the body
  if (method === 'GET') {
     var data = body;
     url = new URL(url, location.protocol + '//' + location.host + '/');
     Object.keys(data).forEach(key => url.searchParams.append(key, data[key]));
     body = undefined;
  }
  return fetch(url, {
    method: method,
    body: body
  }).then(function(res) {
    if (res.ok) return res;
    throw new Error('Server error. Status code: ', res.status);
  }).catch(function(err) {
    console.log(err);
  });
}

// Later...
var myFetch = fetchCall(myUrl, myMethod, myBody);
myFetch.then(function(res) {
  console.log(res);
});

我遇到的问题是if res.ok return res;没有说明它的响应类型(即res.json()res.blob()res.text()等。)< / p>

  

因此,我想知道如何建立一种动态的方式来设置响应体的类型。甚至可以在Fetch API的当前开发状态​​下实现这一点吗?只是在MDN中有一些我没有重复的内容吗?

在弄乱了这个之后,我也意识到我可以将它设置为return res.text();,如果调用应该是JSON,请使用JSON.parse(response);,但我确实想要它要有活力。如果我最终想要返回blob()

,该怎么办?

1 个答案:

答案 0 :(得分:1)

因此,就对话而言,有一种方法可以了解收到的内容类型,并附有两条评论:

  1. 通常,您必须始终了解并期望确切的内容类型,并且在从某个远程端点获取时,通用解决方案相当奇怪,并且
  2. Content-Type标题会告诉您收到的内容类型,但服务器可能会发送错误的标题,这是非常不寻常的,因此可以忽略不计。
  3. Response对象具有header属性{种类} Map,因此您可以使用其get方法按键获取值。

    检查返回值是否是您期望的某种MIME类型的最简单,最干净的方法是使用正则表达式:

    // replace url with the actual API endpoint URL
    fetch(url).then(response => {
      const contentType = response.headers.get('Content-Type'); // -> "text/html; charset=utf-8"
    
      if (/text\/html/i.test(contentType)) {
        // do something when the Content-Type is text/html
      } else if (/application\/json/.test(contentType)) {
        // do something when the Content-Type is application/json
      } 
      // and so on, for every Content-Type you need.
    }).catch(error => {
      // do something when error happens
    });