Angular返回OPTIONS的结果而不是调用的方法

时间:2017-12-14 17:43:11

标签: angular api cors

我有一些Angular 4应用程序,并期待一个奇怪的错误。 有一项服务,我的服务。它有一个请求方法,用于应用程序的其他部分。

(部分观点)

import { Injectable, Inject } from '@angular/core';
import { Http, RequestOptions, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs';
import { SweetAlertService } from 'ng2-sweetalert2';
import { TranslateService } from '@ngx-translate/core';
import { Toast, ToastsManager } from 'ng2-toastr/ng2-toastr';

@Injectable()
export class myService {

    constructor(
        @Inject(SweetAlertService) swal: SweetAlertService,
        private http: Http,
        public toaster: ToastsManager
    ) {
        this._swal = swal;
    }

    public absTop(el) {
        return el.offsetParent ? el.offsetTop + this.absTop(el.offsetParent) : el.offsetTop;
    }

    public post(path: string, requestData?: any, settings?: any) {
        !settings && (settings = {});
        settings.method = 'post';
        return this.request.call(this, path, requestData, settings);
    }

    public get(path: string, requestData?: any, settings?: any) {
        !settings && (settings = {});
        settings.method = 'get';
        return this.request.call(this, path, requestData, settings);
    }

    public request(path: string, requestData?: any, settings?: any): Observable<Response> {
        settings = settings || {};
        var supErr = settings.suppressError;

        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        let options = new RequestOptions({ headers: headers })

        let prefix: string = window['requestUrlPrefix'] || '';

        if (!window['countLoadings']) {
            window['countLoadings'] = 1;
        } else {
            ++window['countLoadings'];
        }

        if (document.body.className.indexOf("load-mask") < 0) {
            document.body.className += " load-mask";
        }

        var toid = setTimeout(function() {
            if (window['countLoadings'] > 0) {
                if (document.body.className.indexOf("load-spinner") < 0) {
                    document.body.className += " load-spinner";
                }
            }
        }, 400);

        let method = settings && settings.method ? settings.method : 'post';
        let obs = this.http[method](prefix + path, JSON.stringify(requestData), options).share();

        if (settings.timeout) {
            obs = obs.timeout(settings.timeout);
        }

        let onErr = (err) => {
            let resp = '';

            let status = err.status ? err.status : err.name;

            if (supErr === true || supErr == status || (Object.prototype.toString.call(supErr) === '[object Array]' && supErr.indexOf(status) >= 0)) {
                // supress the error message
            } else {
                this.swal({
                    text: 'The is an error!<br>' + resp,
                    type: 'error'
                });
            }
            fin();
        };

        let fin = () => {
            setTimeout(() => {
                if (--window['countLoadings'] === 0) {
                    document.body.className = document.body.className.replace(/\bload-mask\b/, '').replace(/\bload-spinner\b/, '');
                    clearTimeout(toid);
                }
            }, 1);
        };

        obs.subscribe(
            fin,
            onErr
        );

        return obs;
    }

后端部分绝对正确。返回所有必需的标头。 CORS始终设置为原点(在开发模式下),因此没有任何问题。

问题部分在这里:

...cut...
export class AppComponent implements OnInit {

constructor(
    public settings: SettingsService,
    public myService: myService,
...cut...
        myService.post('/someEndpoint', null, {
            timeout: 10000,
            suppressError: [412, 403]
        }).subscribe((ret) => {

            console.log(ret);
...cut...

console.log(ret)始终显示浏览器完成的预检请求的结果(正文)。如果我禁用CORS(在Safari中),它可以正常工作,因为返回了正确的数据。但是启用CORS(因为它在prod中),订阅部分中提供了错误的数据。

其他信息(示例):

  • 该应用程序位于app.somedomain.com
  • api可在api.somedomain.com
  • 下找到

这是什么问题? (我不知道Angular:D)

更新

我尝试简单地添加一个方法来进行api调用。看起来像这样:

public test(): Observable<Response> {

        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        let options = new RequestOptions({ headers: headers })

        return this.http
            .post('http://api.somedomain.com/someEndpoint', '{}' ,options)
            .map(response => {
                console.log(response)
                return response
            })
            .catch(this.handleError);
}

我仍然得到浏览器OPTION调用的响应......

我用这种方式调用某个组件中的方法:

this.test = this.myService.test();

1 个答案:

答案 0 :(得分:0)

答案似乎很简单......

options.withCredentials = true失踪了......(在请求中)