在 Observable 中获取 xhr.send() 之后的服务器响应

Getting the server response after xhr.send() in an Observable

我在我的 Angular 2 应用程序中实施了一个方法来 POST 一个文件。它基于我找到的解决方案 .

因为Angular 2 本身不支持文件上传,解决方案必须利用xhr。这是工作解决方案的样子:

组件方法:

onSubmit(): void {
    this.inputModuleService.postFile(this.files).subscribe(() => {
        console.log('sent');
    });
}

服务方式:

postFile (files: File[]): Observable<string> {
    var url = this.uploadURL;

    return Observable.create(observer => {
        var formData: FormData = new FormData()
        var xhr: XMLHttpRequest = new XMLHttpRequest();

        formData.append("upload", files[i], files[i].name);

        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    observer.next(JSON.parse(xhr.response));
                    observer.complete();
                } else {
                observer.error(xhr.response);
                }
            }
        };

        xhr.open('POST', url, true);
        xhr.send(formData);
    });
}

我的问题是我不明白如何在调用 xhr.send() 之后将响应返回给 onSubmit() 方法。 Angular2 以及 observables 和 promises 的概念对我来说都是全新的。

如何从这个 observable 获得服务器的响应?

服务器响应提供给 subscribe() 的成功和错误回调:

onSubmit(): void {
    this.inputModuleService.postFile(this.files).subscribe(
      response => {
          //response is the server's response, parsed into a javascript object
          console.log('server responded: ', response);
      },
      error => {
          //server response emitted when xhr.status !== 200
          console.error(error);
      }
   );
}

这一行:

formData.append("upload", files[i], files[i].name);

将抛出错误,因为 i 未定义。您从中复制的代码在循环中包含该行,i 是当前索引。你的代码不是这种情况。

你的函数声明:

postFile (files: File[]): Observable<string>

应该改为

postFile (files: File[]): Observable<any>

因为 postFile 返回的 Observable 发出对象,而不是字符串。

如果您只想上传一个文件,您还应该将 files: File[] 更改为 file: File 并在文件后附加:

formData.append("upload", file, file.name);