我遇到了一个非常令人沮丧的错误。我不确定发生了什么,但我认为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的标题。
我的问题是我的标头对象(特别是旧的访问令牌)中的值不正确。我注意到的是,当我在分配后添加headersObj
的日志记录语句时,有时它会有过去请求的旧响应头。但是,当我在开发控制台网络选项卡中查看请求本身时,它不会在响应标头中显示任何 auth标头('access-token','client'等等。 )。如果我在浏览器上进行硬刷新,这会得到一段时间的修复,但看起来莫名其妙地回来了。
注意我们正在使用rxjs
来提出我们的请求,这可能是相关的(但我不认为这是导致此问题的原因,因为我正在尝试从原始版本中读取标头{ {1}}对象)。谢谢!
答案 0 :(得分:1)
正如Barmar在评论中所说,这是一个缓存问题。 Chrome控制台中可能存在一个错误,它没有显示缓存请求中的缓存标头。因此即使看起来没有auth标题,也确实存在。
如果你正在使用jQuery,你可以在请求中添加选项cache: false
以防止缓存。因为我不是,我做的第一件事是尝试向每个请求添加?cache=${new Date().toJSON}
,这成功地破坏了缓存并解决了我的问题(这就是jQuery中的cache: false
)。
我们的后端处于轨道状态,因此我最终添加了
before_action :set_cache_headers
...
private
def set_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
end
到我的应用程序控制器。现在浏览器没有缓存任何请求。不确定这是否是我们的长期解决方案