【问题标题】:Http calls are immediately cancelledHttp 调用立即取消
【发布时间】:2017-09-29 22:41:06
【问题描述】:

我有一个 Angular 4 前端和一个 CakePHP 3 后端。当我使用浏览器或 Rest Client 向 API 端点发出请求时,我会收到响应。但是,当我从角度服务发送响应时,它会立即在网络中显示已取消。

起初我认为这是一个 CORS 问题。我已经尝试过启用和不启用 CORS。我还在我的 AppController.php 中添加了$this->Security->csrfCheck = false;,这让我相信本地服务器永远不会被命中(没有断点被触发)。

因此,我正在研究等式的 Angular 方面。我试图设置我的标题,但这也不起作用。

import { Headers, Http, Response, RequestOptions } from '@angular/http';

login(loginData) {
    const headers = new Headers({'Content-Type': 'application/json'});

    const url:string = this.backendUrl + '/auth/login/?';

    return this.Http.post(
        url,
        JSON.stringify(loginData),
        { headers: headers }
    ).map(
        res => res.json
    ).map(
        response => function(response) {
            ...
        },
        error => function(error) {
            ...
        }
    );
}

我正在从 1 迁移到 4。所以我知道它可以在 Angular 1 中使用 $http 请求。

function login(loginData) {
   var = this.backendUrl + '/auth/login/?';

   $http.post(url, loginData).then( ... );
}

这是我使用订阅的组件:

login = function(activeUser):ActiveUser|boolean {
    this.isLoggingIn = true;

    return this.LoginService.login(activeUser).subscribe(
        activeUser => function(activeUser) {
            if (activeUser) {
                this.activeUser = activeUser;
            } else {
                this.reset();
            }

            return activeUser;
        }.bind(this)
    ).complete(
        function() {
            this.isLoggingIn = false;
        }.bind(this)
    );
};

【问题讨论】:

  • angular http observables 默认是冷的。这意味着您的登录功能只是设置http请求。要真正发起 http 请求,您必须订阅可观察的 this.login.subscribe();
  • 这个问题略有不同,正在向网络发起呼叫并被取消。我的问题似乎与未正确设置订阅方法有关。另一个问题是完全缺少导致根本没有调用的 subscribe 方法。不过,它帮助我走上了正轨,谢谢!

标签: angular cors cakephp-3.0


【解决方案1】:

我不确定您为什么要映射两次。

只是为了比较......这就是我的帖子的样子(见下文)。它正在发布保存,但登录的语法应该相同。

   saveProduct(product: IProduct): Observable<IProduct> {
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers });

        return this.http.post(this.baseUrl, product, options)
            .map(this.extractData)
            .do(data => console.log('createProduct: ' + JSON.stringify(data)))
            .catch(this.handleError);
    }

    private extractData(response: Response) {
        let body = response.json();
        return body.data || {};
    }

    private handleError(error: Response): Observable<any> {
        // in a real world app, we may send the server to some remote logging infrastructure
        // instead of just logging it to the console
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }

你怎么称呼这个服务?

我的组件代码如下所示:

        this.productService.saveProduct(this.product)
            .subscribe(
                () => this.onSaveComplete(`${this.product.productName} was saved`),
                (error: any) => this.errorMessage = <any>error
            );

请注意,启动 Observable 并执行帖子的是订阅。

【讨论】:

  • 当我尝试得到Property 'do' does not exist on type 'Observable'
  • 您可以删除它(它仅用于调试),也可以导入 do 运算符。 import 'rxjs/add/operator/do';
  • 我已经包含了调用subscribe的组件。我也试过删除第二个map 电话,但没有运气。
  • 当我使用空的subscribe 方法时,它似乎可以工作。
【解决方案2】:

问题与 Angular $http 现在如何处理 CORS 请求有关。在更新版本中,发送了两个请求,一个 OPTIONS 请求,然后是实际的 GET/POST 请求。所以我不得不更改我的后端以在 OPTIONS 上返回 200 而不执行命令,而是在第二个请求上执行。

【讨论】:

    猜你喜欢
    • 2014-07-04
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 2019-11-03
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多