http.request 在实际响应之前返回"{ type: 0 }"



每次提交登录表单时,Login()方法(如下所示)代码中的return res;都会执行两次。

第一个响应是一个简单的对象{ type: 0 },第二个是我正在寻找的实际响应。

为什么return res;会被呼叫两次?如何防止这种情况发生?

我已经遍历了代码,并确认login()只被调用一次,我的HttpInterceptor只被调用了一次,远程请求只被发送了一次。

我上传了这张图片来帮助解释发生了什么。您可以看到,只有1个远程请求被执行,但有2个响应被记录到控制台。

这个问题几个小时前才开始。我一直在努力让ionic serve与CORS一起工作,我尝试使用proxy.conf.jsonproxy.js,但如果不能访问API,我就无法允许访问。出于开发目的,我使用这个扩展在Chrome中禁用了CORS,因为一旦我在移动设备上运行该应用程序,它就不需要CORS了。

我尝试过的其他toubleshooting:

  1. 在Chrome中禁用了Allow Control Allow Origin:*扩展,问题仍然存在
  2. 我从app.module.ts中删除了HttpInterceptor,问题仍然存在
  3. 我尝试过不同的远程URL(甚至是localhost),但问题仍然存在
  4. 关闭Chrome并重新启动电脑,问题仍然存在
  5. 尝试使用FireFox,但问题仍然存在
  6. 我创建了一个新的Ionic4项目,并复制/粘贴了相同的代码,但问题仍然存在
  7. 我在另一台机器上试用了Chrome,但问题仍然存在

这是在我的onSubmit()方法中订阅的login()可观测值:

login(username: string, password: string) {
const body = new FormData();
body.append('username', username);
body.append('password', password);
const request = new HttpRequest('POST', '[URL]', body);
return this.http.request(request)
.pipe(map(res => {
return res;
}));
}

如果有帮助的话,这是我的onSubmit()HttpInterceptor

onSubmit () {
this.isSubmitted = true; // I've put a break point here to make sure this method is called once
if (!this.login.valid) {
return;
}
this.authenticationService.login(this.login.value.username, this.login.value.password).subscribe((res: any) => {
console.log(res); // this is the log that is displayed in the above screen shot
});
}
export class AuthInterceptor implements HttpInterceptor {
constructor() { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Check auth here...
return next.handle(request);
}
}

我希望return res;只被调用一次。

原来我需要更改

login(username: string, password: string) {
const body = new FormData();
body.append('username', username);
body.append('password', password);
const request = new HttpRequest('POST', '[URL]', body);
return this.http.request(request)
.pipe(map(res => {
return res;
}));
}

到以下

login(username: string, password: string) {
const body = new FormData();
body.append('username', username);
body.append('password', password);
return this.http.post<any>(`[URL]`, body)
.pipe(map(res => {
return res;
}));
}

我看不出你提到的代码中有任何问题,但根据你所描述的,似乎你已经为http请求设置了一些选项,响应是观察事件而不是响应。

options: {
headers?: HttpHeaders | {[header: string]: string | string[]},
observe?: 'body' | 'events' | 'response',
params?: HttpParams|{[param: string]: string | string[]},
reportProgress?: boolean,
responseType?: 'arraybuffer'|'blob'|'json'|'text',
withCredentials?: boolean,
}

observe选项指定返回多少响应。此链接可能有助于

简短回答:不要使用http.request(),使用http.post()或类似的。

长答案:

您正在将HttpClient.request()HttpRequest对象一起使用,并且request()上的文档表示,在这种情况下,您在所有HttpEvents的流上获得一个Observable。对象

{ type: 0 }

只是Sent类型的第一个HttpEvent,在发送请求之后但在响应到达之前直接发出。然后的响应是之后的下一个事件。(有关所有可能的事件,请参阅HttpEventType)要只获得响应,您可以简单地使用另一种方法(或根据文档修改您对request()的调用)

请使用单个return语句,而不是返回2次尝试使用以下代码,感谢

login(username: string, password: string) {
const body = new FormData();
body.append('username', username);
body.append('password', password);
const request = new HttpRequest('POST', '[URL]', body);
this.http.request(request)
.pipe(map(res => {
return res;
}));
}

最新更新