从 xmlHttpRequest 检索结果
retrieve result from xmlHttpRequest
我必须为我的 angular 项目转换本地音频。我找到的唯一方法是通过 XMLHttpRequest :
var xhr = new XMLHttpRequest();
xhr.open("GET", "/path/to/local/image/file", true);
xhr.responseType = "blob";
xhr.onload = function (e) {
console.log(this.response);
var reader = new FileReader();
reader.onload = function(event) {
var res = event.target.result;
console.log(res)
}
var file = this.response;
reader.readAsDataURL(file)
};
xhr.send()
“res”为我的音频提供了 base64。但是我无法检索 res 并将其存储在变量中以在另一个函数中使用它。
我怎样才能做到这一点 ?还有比使用 XMLHttpRequest 更好的方法吗?
提前致谢。
我建议您使用 Angular HTTP 模块。它是 Angular 原生的,因此更容易与应用程序的其他部分集成。
然后您可以使用一个容器(比如 RxJS ReplaySubject
和缓冲区 1)来 cache/hold 来自 HTTP 请求和后续 FileReader
的 onload
的值回调。
注意:由于这都是异步的,因此任何直接依赖于 HTTP 请求结果的语句都必须在订阅内。有关异步数据如何工作的详细信息,请参阅 here。
app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { HttpClientModule } from "@angular/common/http";
import { AppComponent } from "./app.component";
import { DataService } from './data.service';
@NgModule({
imports: [BrowserModule, FormsModule, HttpClientModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [DataService]
})
export class AppModule {}
data.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http"; // <-- import `HttpClient`
import { Observable, ReplaySubject } from 'rxjs';
@Injectable()
export class DataService {
private fileSource: ReplaySubject<any> = new ReplaySubject<any>(1);
public file$: Observable<any> = this.fileSource.asObservable();
constructor(private http: HttpClient) { // <-- inject `HttpClient`
this.getFile(); // <-- trigger file fetch here
}
getFile(): void {
this.http.get('/path/to/local/image/file', { responseType: "blob" }).subscribe({ // <-- add `responseType`
next: (response: any) => {
const reader = new FileReader();
reader.onload = (event) => { // <-- arrow function
this.fileSource.next(event.target.result); // <-- push to the `ReplaySubject`
}
reader.readAsDataURL(response) // <-- should NOT be `this.response`
},
error: (error: any) => {
// handle error
}
});
}
}
app.component.ts
import { Component, OnInit, OnDestroy } from "@angular/core";
import { Subject } from "rxjs";
import { takeUntil } from "rxjs/operators";
import { DataService } from "./data.service";
@Component({ ... })
export class AppComponent implements OnInit, OnDestroy {
close$ = new Subject<any>();
file: any;
constructor(private _data: DataService) { }
ngOnInit() {
this._data.file$.pipe(
takeUntil(this.close$)
).subscribe({
next: (file: any) => {
this.file = file;
// other statements that depend on `this.file`
}
});
}
ngOnDestroy() {
this.close$.next(); // <-- close open subscriptions
}
}
更新
- 将
responseType
添加到 GET 请求
- 工作示例:Stackblitz
我必须为我的 angular 项目转换本地音频。我找到的唯一方法是通过 XMLHttpRequest :
var xhr = new XMLHttpRequest();
xhr.open("GET", "/path/to/local/image/file", true);
xhr.responseType = "blob";
xhr.onload = function (e) {
console.log(this.response);
var reader = new FileReader();
reader.onload = function(event) {
var res = event.target.result;
console.log(res)
}
var file = this.response;
reader.readAsDataURL(file)
};
xhr.send()
“res”为我的音频提供了 base64。但是我无法检索 res 并将其存储在变量中以在另一个函数中使用它。 我怎样才能做到这一点 ?还有比使用 XMLHttpRequest 更好的方法吗? 提前致谢。
我建议您使用 Angular HTTP 模块。它是 Angular 原生的,因此更容易与应用程序的其他部分集成。
然后您可以使用一个容器(比如 RxJS ReplaySubject
和缓冲区 1)来 cache/hold 来自 HTTP 请求和后续 FileReader
的 onload
的值回调。
注意:由于这都是异步的,因此任何直接依赖于 HTTP 请求结果的语句都必须在订阅内。有关异步数据如何工作的详细信息,请参阅 here。
app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { HttpClientModule } from "@angular/common/http";
import { AppComponent } from "./app.component";
import { DataService } from './data.service';
@NgModule({
imports: [BrowserModule, FormsModule, HttpClientModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [DataService]
})
export class AppModule {}
data.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http"; // <-- import `HttpClient`
import { Observable, ReplaySubject } from 'rxjs';
@Injectable()
export class DataService {
private fileSource: ReplaySubject<any> = new ReplaySubject<any>(1);
public file$: Observable<any> = this.fileSource.asObservable();
constructor(private http: HttpClient) { // <-- inject `HttpClient`
this.getFile(); // <-- trigger file fetch here
}
getFile(): void {
this.http.get('/path/to/local/image/file', { responseType: "blob" }).subscribe({ // <-- add `responseType`
next: (response: any) => {
const reader = new FileReader();
reader.onload = (event) => { // <-- arrow function
this.fileSource.next(event.target.result); // <-- push to the `ReplaySubject`
}
reader.readAsDataURL(response) // <-- should NOT be `this.response`
},
error: (error: any) => {
// handle error
}
});
}
}
app.component.ts
import { Component, OnInit, OnDestroy } from "@angular/core";
import { Subject } from "rxjs";
import { takeUntil } from "rxjs/operators";
import { DataService } from "./data.service";
@Component({ ... })
export class AppComponent implements OnInit, OnDestroy {
close$ = new Subject<any>();
file: any;
constructor(private _data: DataService) { }
ngOnInit() {
this._data.file$.pipe(
takeUntil(this.close$)
).subscribe({
next: (file: any) => {
this.file = file;
// other statements that depend on `this.file`
}
});
}
ngOnDestroy() {
this.close$.next(); // <-- close open subscriptions
}
}
更新
- 将
responseType
添加到 GET 请求 - 工作示例:Stackblitz