【发布时间】:2018-05-28 21:24:09
【问题描述】:
我有一些 Angular 4 应用程序,并期待一个奇怪的错误。 有一个服务,myService。它有一个请求方法,用于应用程序的其他部分。
(部分视图)
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();
【问题讨论】:
-
什么是jfs? myService taht 的实例包装了 http 服务?看起来你是直接调用请求,这不应该这样做,因为你没有设置方法
-
抱歉,更新了代码。应该怎么称呼?
-
这个服务不是你写的吗?您需要为您正在尝试执行的操作调用正确的 http 请求类型,例如 get、put、post、delete...请求实际上应该是仅由服务内部使用的私有方法
-
这不是我的代码,但我必须修复它...如我所见,post 被称为默认方法类型 (
this.http[method])。即使在 AppComponent 中改成post也没有变化 -
它没有正确完成,这整件事绝对是一团糟。不知道你从哪里弄来的,但我的建议是把它扔掉,永远不要再使用给你这个的人的代码