【问题标题】:Angular 4 http responses are mixed togetherAngular 4 http响应混合在一起
【发布时间】:2018-05-08 08:33:15
【问题描述】:

我使用的是 Angular 4。这个问题已在 safari、chrome 和 Firefox 中发现。

我的 Angular 4 应用程序使用 httpclient 将 XHR 请求发送到 REST 服务。使用 JSON 进行通信。

存在潜在的 CORS 问题,因此浏览器会发送飞行前 OPTIONS 请求。

请求以 JSON 格式返回用户详细信息。

有时(可能五分之一),我会看到综合反应:

例如,如果两个请求快速连续发送(相同的 URL),我会看到: 选项请求已发送 已发送选项请求 GET 请求已发送(无响应) 已发送 GET 请求(结果与最后返回的 GET 相结合)

所以对于最后一个 GET,我会收到:

{"username":"Dave Smith","badge":"12345", "lockPollTime":61000}{"username":"Dave Smith","badge":"12345", "lockPollTime":61000}

(即:两个 JSON 对象共同加入,这是一个 JSON 语法错误,因此应用程序中断) .. 而我希望这两个 GET 各收到一个:

{"username":"Dave Smith","badge":"12345", "lockPollTime":61000}

我在其他请求中也看到了这一点,但 URL 不同(相同的服务器和 REST 服务,不同的操作)。

从 authService 服务获取登录信息的调用如下所示:

login(username: string, password: string): Observable<LoginResponse|boolean> {
    return this.http.get(ApiRoutes.auth.login, this.loginHeaders(username, password)).map((response: Response) => {
        if(response.headers.get('Content-Type').indexOf('text/html') !== -1) {
            return false;
        }

        return new LoginResponse(response);
    });
}

对它的调用是这样的:

this.authService.login(username, password).subscribe(
    (user: LoginResponse|boolean) => { .. etc etc } )

用户凭据通过 n 拦截器提供:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if(this.authService.getAuthToken()) {
        request = request.clone({
            setHeaders: {
                Authorization: `Basic ${this.authService.getAuthToken()}`
            }
        });
    }

    return next.handle(request);
}

如果我在浏览器窗口中尝试其中一个 REST 服务 URL 并多次按 F5,则无法重现该问题。似乎只是有角度的 http 请求,虽然我不知道这是否是一个公平的测试。

我不确定这是不是..

  • Angular 订阅问题
  • httpclient 错误
  • 服务器端出现问题(难以想象)

如果有人能对此有所了解,我将不胜感激,我会在大街上通过扩音器高呼您的用户 ID。

我唯一的线索是有时会发送异步请求(例如心跳“ping”),这些有时似乎与用户发起的请求发生冲突(例如保存,使用 POST 请求或 GET 获取一些其他信息)。

感谢您的任何帮助或建议。

【问题讨论】:

  • 你试过switchmap吗?
  • @JanSomersJanS91 感谢您的建议,恐怕我不明白其中的哪一部分会有所帮助,因为它似乎可以做很多事情

标签: javascript json angular xmlhttprequest angular4-httpclient


【解决方案1】:

只需将 ma​​p 替换为 switchmap,它会自动取消除最后一个之外的所有请求。

更多信息:Search with switchmap

编辑:例如,如果您有 2 个不同的功能

     http.get(API_URL1).switchmap(...)
     http.get(API_URL2).map(...) 

switchmap 只能取消来自 API_URL1 的旧请求。或者即使你有这样的东西:

     http.get(API_URL1).switchmap(...)
     http.get(API_URL2).switchmap(...)

同时有来自 URL1 和 URL2 的请求很好,因为每个 switchmap 只能取消来自其 URL 的旧请求。

希望这能消除您的困惑。

【讨论】:

  • 感谢负载的响应,但据我了解,当一些“较旧”的 http 请求完成时,这将有效地取消触发的事件。由于不同的 URL 也会发生这种情况,因此如果保存完成的时间比同时其他请求的时间长,它最终不会对(例如)保存完成做出反应。我这样想对吗?
  • 对不起,我不够清楚,切换地图将取消您正在使用的可观察对象中的所有旧订阅,因此不同的 URL 不会发生这种情况。即使你在多个请求上使用 switchmap,每个 switchmap 都会取消它自己的请求,并且不会干扰其他请求。
  • @Alex,请更新您的答案。否则会被删除。
  • @Alex 啊,是的,我明白了,感谢您的更新。我已经投了赞成票,但会等着看其他人是否回复。我认为这是一种解决方法而不是修复?混合来自两个不同请求的响应,即使来自两个不同的 URL,这似乎真的很奇怪。 (为什么那会是可取的?)我有一种感觉,如果可能的话,我一定会错过一些基本的东西,即使使用 .map() 也是如此。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-20
  • 2017-10-25
  • 1970-01-01
  • 2019-03-28
  • 2018-01-31
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多