我有一个Angular 5应用程序试图通过HTTP-GET API调用加载产品并在iOS Safari和Mac OS Safari上崩溃。
我第一次访问页面时一切正常,但是第二次我的Angular应用程序崩溃后,因为HTTP-GET没有返回预期的值。
我检查了开发人员控制台,结果发现Safari不会从我的域中发送GET工作所需的cookie。
它说请求来自硬盘缓存。 我检查了我的服务器上的日志文件,Safari实际上调用了我的API(尽管它说它使用了硬盘缓存)但没有cookie。
我的Angular应用程序中的HTTP-GET如下所示:
this.noCacheHeader = new HttpHeaders()
.append('Cache-Control', 'no-cache')
.append('Cache-control', 'no-store')
.append('Expires', '0')
.append('Pragma', 'no-cache');
get<T>(url: string): Observable<T> {
return this.http.get<T>(this.baseUrl + url, { withCredentials: true, headers: this.noCacheHeader });
}
由于IE11的缓存问题,我已经禁用了缓存。
如何告诉Safari始终发送我的Cookie?
更新1:
我在我的HTTP-GET查询“products?ticks = 1337”中添加了一个ticks参数,现在它可以工作了。所以它必须与缓存有关。
答案 0 :(得分:0)
一种方法是使用自定义Http拦截器:
// custom.interceptor.ts
@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
intercept (httpRequest: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
const clonedRequest = httpRequest.clone({
withCredentials: true
});
return next.handle(clonedRequest);
}
}
然后引用app.module.ts
中的拦截器:
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { CustomHttpInterceptor } from 'your-module;
@NgModule({
...,
imports: [
...,
HttpClientModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: CustomHttpInterceptor,
multi: true
},
],
})
withCredentials: true
是拦截器的重要组成部分。设置此选项应该在每次请求时都返回cookie。
有关详细信息,请参阅:https://angular.io/api/http/RequestOptions和https://fetch.spec.whatwg.org/#cors-protocol-and-credentials。
如果你已经这样做了,那很可能是一个缓存问题。尝试将Cache-Control
标头设置为更具限制性:
setHeaders: {
"Cache-Control": "private, no-cache, no-store, must-revalidate"
}
或者最后,将querystring参数附加到始终唯一的请求,例如UNIX时间戳。
答案 1 :(得分:0)
可能不一样,但是Safari也有类似的问题。我在jquery加载的html中使用了<audio>
标签。 Safari在音频源请求中未包含cookie,因此无法正确加载。但是在我用CTRL + F5刷新页面后,它以某种方式起作用-它发送的Cookie的总重载...
我通过添加crossorigin="use-credentials"
...令人讨厌的问题来解决它。