Fetch Promise 被 Chrome 的缓存阻止

Posted

技术标签:

【中文标题】Fetch Promise 被 Chrome 的缓存阻止【英文标题】:Fetch Promise gets blocked by Chrome's Cache 【发布时间】:2018-02-19 17:56:11 【问题描述】:

我正在尝试将 Fetch API 与 Promise 一起使用,并且我对 API 进行了以下调用。

export const refreshTokenAPI = () => 
  return fetch('/api/auth/gettoken/' ,
    cache: 'no-store',
    headers: 
      'Authorization': 'Basic '+ btoa(getToken() + ':'),
      'pragma': 'no-cache',
      'cache-control': 'no-cache'
   
  )
    .then(response => 
      return handle_response(response)
    )
    .catch(error => 
      throw error;
    )
;

当我尝试调用它时,响应只是处于“待处理”状态并且不会从那里去任何地方。奇怪的是,当我从开发控制台内部禁用缓存时,它解决得很好。从 sn-p 中可以看出,我已经尝试了很多方法来禁用调用本身的缓存,但它们都没有做任何事情。

我什至在端点本身上尝试过老式缓存破坏,所以我完全不知所措!有什么想法吗?

编辑:事实证明,如果您等待足够长的时间(约 40 秒),它最终会在启用缓存的情况下解决...不知道为什么缓存会导致它挂得这么严重?

【问题讨论】:

打电话handle_reponse(response)之前是不是少了一步?首先从响应中返回json (return response.json()),然后处理结果。 句柄响应包含return response.json() 本身:const handle_response = (response) => if (response.ok) return response.json(); throw response ; 那我总是可以先尝试调用它? 处理handle_response结果的下一个.then()阶段在哪里?我的意思是response.json() 刚刚尝试将return response.json() 移动到它通常所在的位置,并且您会得到相同的效果:如果缓存被禁用,则工作正常,否则将永远挂起:( 您可以尝试禁用所有插件吗?大多数情况下,这可能是一个插件问题。 【参考方案1】:

所以我找到了一个解决方案,它实际上在后端,并且似乎与缓存无关。

我使用 Python/Flask 作为路由器,通过允许线程 (app.run(debug=True, threaded=True, port=5000)),问题就消失了。我不知道为什么会这样,但你有它。

我实际上咬了一个重现问题的最小烧瓶应用程序。它只需要 python 3 和 Flask 即可运行。它在github here,但这里是代码:

应用程序.py:

from flask import Flask, render_template, jsonify

application = Flask(__name__)


@application.route('/')
def index():
    return render_template('index.html')

@application.route('/foo/', methods = ['GET'])
def get_foo():
    return jsonify('message': 'bar'), 200

if __name__ == '__main__':
    # application.run(threaded = True) # This works
    application.run()                # This doesn't

/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>

<body>
Loaded...
</body>

<script>
document.addEventListener("DOMContentLoaded", function(event) 
  console.log('document ready');

  fetch('/foo/').then(function(response) 
    console.log('then triggered');
    return response.json();
  ).then(function(json) 
   console.log(json)
  );
);
</script>

</html>

很难相信这么标准的东西竟然不能工作!

【讨论】:

以上是关于Fetch Promise 被 Chrome 的缓存阻止的主要内容,如果未能解决你的问题,请参考以下文章

如何从fetch获取响应值而不是没有值的promise?

fetch用法

fetch()的用法

为啥 fetch 返回 promise 未决?

[转] 学会fetch的用法

将 fetch 包装在 Promise 中有啥好处? [复制]