私はいくつかのAngular 4アプリケーションを用意しており、奇妙なバグが予想されます。 myServiceというサービスがあります。それは、アプリケーションの他の部分で使用されるリクエストメソッドを持っています。角度の結果はOPTIONSの結果であり、呼び出されるメソッドではありません。
(部分図)
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は常に(dev-modeの)原点に設定されているため、問題はありません。
問題の一部はここにある:
...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のf.e.)を無効にすると、適切なデータが返されるので問題なく動作します。しかし、有効になっているCORS(プロダクトにあるように)では、間違ったデータが購読セクションで利用可能です。
追加情報(例):
- アプリは
app.somedomain.com
- 下のAPI提供されています
api.somedomain.com
の下で提供されていますが、ここで問題とは何ですか?私は単にAPI呼び出しを行うためのメソッドを追加してみました
UPDATE:(D私は角については考えています)。それは以下のようになります
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();
がありませんでしたか? myServiceのisntanceはHTTPサービスをラップしますか?あなたが直接リクエストを呼び出すように見えますが、方法を設定していないので決して実行しないでください。 – bryan60
申し訳ありませんが、コードを更新しました。どのように呼び出されるべきですか? – x4k3p
あなたはこのサービスを書いていませんか?あなたは何をしようとしているのか、適切なhttpリクエストタイプを呼び出す必要があります。たとえば、get、put、post、delete ...リクエストは実際にはサービス内でのみ使用されるprivateメソッドです。 – bryan60