【问题标题】:iOS Safari and Mac OS Safari don't send cookiesiOS Safari 和 Mac OS Safari 不发送 cookie
【发布时间】:2018-11-18 08:51:00
【问题描述】:

我有一个 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 参数,现在它可以工作了。所以它一定和缓存有关。

【问题讨论】:

  • 我在 Safari 上遇到了同样的问题。我不得不去偏好->隐私->取消选中“防止跨站点跟踪”
  • 谢谢@BradenBrown,就我而言,这是未通过请求发送 cookie 的根本原因。

标签: angular safari


【解决方案1】:

可能不一样,但我在 Safari 上遇到了类似的问题。我在 jquery 加载的 html 中使用了&lt;audio&gt; 标签。 Safari 在对音频源的请求中未包含 cookie,因此无法正确加载。但不知何故,在我用 CTRL+F5 刷新页面后它就起作用了——它发送了完全重新加载的 cookie...

我通过添加 crossorigin="use-credentials"... 解决了这个问题。

【讨论】:

    【解决方案2】:

    一种方法是使用自定义的 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/RequestOptionshttps://fetch.spec.whatwg.org/#cors-protocol-and-credentials

    如果您已经这样做了,则可能是缓存问题。尝试将 Cache-Control 标头设置得更严格:

    setHeaders: {
      "Cache-Control": "private, no-cache, no-store, must-revalidate"
    }
    

    或者最后,将查询字符串参数附加到始终唯一的请求中,例如 UNIX 时间戳。

    【讨论】:

    • 我更新了答案,因为我在通话中实际上使用了“withCredentials: true”。
    • 明白了。这听起来确实像一个缓存问题。
    猜你喜欢
    • 2017-09-03
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 2015-10-26
    • 2018-04-30
    • 1970-01-01
    相关资源
    最近更新 更多