【问题标题】:Cross browser fetch response validation跨浏览器获取响应验证
【发布时间】:2021-03-04 22:52:29
【问题描述】:

如何以跨浏览器工作的方式检查来自 JavaScript 提取的响应是否有效(状态 200)?

我找到的唯一解决方案是将响应读取为 ArrayBuffer 并逐字节手动检查内容以查看它是否是有效文件。不太实用。

在我的情况下,获取是在服务工作者中,所以我不知道正在获取什么样的资源(html 文档、图像、二进制文件等),我只想根据它采取不同的操作成功与否。

fetch('http://example.com/some_resource')
.then(function(response)
{
   if (response.ok)
   {
       // Works for most browsers, but not Chrome and Firefox on Android 
   }
   response.arrayBuffer().thenCheckEveryByteOfTheFile;  // Do I really have to do this?
});

更新: MDN 文档是错误的。 Response.ok 是为 Android 上的 Chrome 和 Firefox 定义的。

https://github.com/mdn/browser-compat-data/issues/9309

【问题讨论】:

  • 你如何定义“有效”。您正在命名很多不同的格式,包括“二进制文件”。为什么要逐字节检查?肯定有一种更快的方法可以确保至少其中一些格式的有效性?
  • @Evert:最简单的方法是如果我可以访问 HTTP 响应的第一行,通常是“HTTP/1.1 200 OK”。然后我可以解析它,看看它是否成功。但由于并非所有浏览器都可以访问它,所以我必须读取响应负载,然后如果 URL 以“.jpg”结尾,请检查第一个字节是否为 FF D8 FF。我认为你说对了。对于本应非常简单的事情来说极其不切实际。
  • @Evert:我有 HTML 文件、CSS 文件、字体文件、WEBP 文件、JPG 文件,以及来自 CGI 脚本的许多不同类型的二进制响应。
  • 好吧,你对“有效”的定义有点不同。您正在寻找成功的响应,这是有道理的。为什么 response.ok 在 chrome 和 firefox 上不适合你?
  • 我怀疑这与 CORS 有关

标签: javascript httpresponse fetch-api


【解决方案1】:

不幸的是,截至今天,MDN 表示,fetch() 对象的属性并不(官方)完全兼容,尤其是在移动端与 Android 上的 Chrome/Firefox/Opera 兼容。

这不是您的选择,因为您使用的是 Service Worker,它已放弃常规 Ajax 支持。 XHR 不会在那里定义,您只能使用fetch() API。

否则,您可以使用XMLHttpRequest,它保留了完整的官方跨浏览器兼容性。

let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/some_resource');
xhr.send();

//When response is received
xhr.onload = function() {
  if (xhr.status == 200) { // xhr.status is compatible with Android
        console.log(xhr.response); 
        //OK!
  } else { 
        console.log(xhr.response); 
        //OOPS, not OK!
  }
};

不管怎样,如果你尝试编写这个脚本:

window.onload = function() {
    fetch('https://whateverfreeapiyoucanthink.of')
    .then(function(response)
    {
       alert(response.status);
    });
    }

然后从 Android 设备打开页面,它对我来说都适用 Chrome 88Firefox 86 使用 Android 8.0.0,虽然它不受官方支持。如果没有,这值得注意,因为它会证明 MDN 是错误的。

【讨论】:

  • 谢谢,但没有为 Android 上的 Chrome 和 Firefox 定义 response.status 和 response.statusText。如果有办法访问 HTTP 响应的状态行,那就很简单了。 developer.mozilla.org/en-US/docs/Web/API/Response
  • 感谢@BiOS,您的建议在客户端非常有用。但是我的代码在服务工作者中,据我了解,不能保证在那里定义 XHR,因为它是一个遗留 API。让我感到困扰的是 Response 对象无法访问整个 HTTP 响应,只有一些浏览器丢弃状态部分的解析版本。这对我来说毫无意义。我在这里误解了什么吗?
  • 你在 XHR 上确实又是对的,事实上我不知道它对服务人员的支持下降了。我再次更新了答案,以反映您提供的良好信息,而不是误导任何人。但是,出于好奇,我正在运行一些测试,我注意到alert(response.status)(没有适当控制台的情况下我可以尝试的最好的方法)实际上适用于 Android 8 上的 Firefox 和 Chrome。这意味着 response.status 实际上已被读取。但是,我猜你已经尝试过了,不管 MDN 警告如何?
  • 感谢测试。不,我实际上并没有尝试过。 MDN 通常总是正确的,他们是 Firefox 背后的开发者,所以他们应该知道。谷歌的开发页面指的是 MDN。我已经在 Github 上对此发表了评论。让我们看看他们是如何回应的。 github.com/mdn/content/issues/2785
  • 确实,看到了!正如您从here 看到的那样,他们已经提出了response.status 的观点,但是他们也在等待创建另一个问题,然后再解决response.status... 也许最好创建一个关于整个响应对象!顺便说一句,caniuse 现在也反映了正确的info
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 2016-11-19
  • 2013-06-30
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
相关资源
最近更新 更多