【问题标题】:xhr caching values from getResponseHeader?xhr 缓存来自 getResponseHeader 的值?
【发布时间】:2017-05-09 08:30:48
【问题描述】:

我遇到了一个非常令人沮丧的错误。我不确定发生了什么,但我认为 xhr 正在对响应标头进行某种缓存。

我的应用正在使用 devise_token_auth 作为后端身份验证服务。我们将它与旋转访问令牌一起使用,因此我编写了一个在每个请求之后运行的函数。

function storeAndGetResponseHeaders(xhr) {
    const headersObj = {};

    headerKeys.filter((key) => xhr.getResponseHeader(key))
    .forEach((key) => {
        headersObj[key] = xhr.getResponseHeader(key);
        window.sessionStorage.setItem(key, xhr.getResponseHeader(key));
    });

    return headersObj;
}

其中headerKeys['access-token', 'client', 'expiry', 'uid', 'token-type']。因此,任何具有这些标头的响应都应该将它们保存到 sessionStorage 中,然后将它们返回到一个对象中,该对象存储在我编写并添加到每个请求中的 AJAX 服务中。我们正在使用rxjs,这个服务只是它的一个薄包装。这就是RxAjax.ajax 的样子。

ajax(urlOrRequest) {
    const request = typeof urlOrRequest === 'string' ? { url: urlOrRequest } : urlOrRequest;
    request.headers = Object.assign({}, this.headers, urlOrRequest.headers);
    request.url = `${this.baseUrl}${request.url}`;

    return Observable.ajax(request).map(this.afterRequest, this);
}

其中this.headers 是上次请求中存储的标头(或从 sessionStorage 中加载的标头)。 this.afterRequest 是设置响应 xhr 的标头。

我的问题是我的 headers 对象(特别是旧的访问令牌)中的值不正确。我注意到的是,当我在分配后添加headersObj 的日志记录语句时,有时它会有来自过去请求的旧响应标头。但是,当我在开发控制台网络选项卡中查看请求本身时,它不会在响应标头中显示 任何 身份验证标头(“访问令牌”、“客户端”等。 .)。如果我在浏览器上进行硬刷新,这会得到一段时间的修复,但似乎莫名其妙地回来了。

请注意,我们使用rxjs 发出请求,这可能是相关的(但我认为这不是导致此问题的原因,因为我正在尝试从原始xmlhttprequest 中读取标题目的)。谢谢!

【问题讨论】:

  • 您确定它完全在发送请求,而不仅仅是使用缓存的响应吗?尝试在 URL 中添加缓存清除器。
  • 你是对的!谢谢!我最终在每个请求上设置了 response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" (在 rails 中)。请随意回答问题,以便我接受!
  • 我不知道 Rails。您可以回答自己的问题。
  • 伙计,这是一个棘手的问题,浪费了一整天的时间来解决它,感谢您提出这个问题并回答它!

标签: javascript ajax xmlhttprequest rxjs


【解决方案1】:

正如 Barmar 在 cmets 中所建议的,这是一个缓存问题。 chrome 控制台中可能存在错误,它没有显示缓存请求中的缓存标头。因此,即使看起来确实没有 auth 标头。

如果您使用 jQuery,您可以在请求中添加选项 cache: false 以防止缓存。因为我不是,所以我做的第一件事是尝试将?cache=${new Date().toJSON} 添加到每个请求中,这成功地破坏了缓存并解决了我的问题(这就是 jQuery 中的cache: false 所做的)。

我们的后端在 Rails 中,所以我最终添加了

before_action :set_cache_headers

...

private

def set_cache_headers
  response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
end

到我的应用程序控制器。现在浏览器没有缓存任何请求。不确定这是否是我们的长期解决方案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-28
    • 2011-04-02
    • 2023-03-25
    • 2018-01-06
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    相关资源
    最近更新 更多