在我的 Angular 应用程序中,我有一个上传页面。上传由服务处理并由 NGRX 效果触发。
// service
public upload(file: File): any {
const formData: FormData = new FormData();
formData.append('file', file, file.name);
// create a http-post request and pass the form
// tell it to report the upload progress
const request = new HttpRequest('POST', url, formData, {
reportProgress: true
});
return this.httpClient.request(request);}
// Effect
@Effect({ dispatch: false })
uploadFile = this.actions
.ofType(ActionTypes.UploadFile)
.map(toPayload)
.switchMap(file =>
this.service.upload(file).map(event => {
if (event.type === HttpEventType.UploadProgress) {
// calculate the progress percentage
const percentDone = …Run Code Online (Sandbox Code Playgroud) 我在 app.module.ts 中实例化 MyService,并在我的代码中提供它。
但是,我希望 MyService 使用 httpClient,并且我无法以角度惯用方式实例化 httpClient 以作为参数传递给 MyService。我不确定在 MyService 中访问 httpClient 的正确方法是什么。
我考虑过直接实例化 httpClient ,然后将其作为参数传递给我的服务。然而,这似乎造成了循环依赖。我也尝试过弄乱注入器,但显然 Angular 团队特别建议不要这样做。我强烈地觉得我错过了一些简单的东西。
应用程序模块.ts
imports: [
...
httpClientModule
...
],
function MainServiceFactory() {
return new MyService();
}
...
providers: [{
provide: MyService,
useFactory: MainServiceFactory
}],
...
Run Code Online (Sandbox Code Playgroud)
MyService.ts
...
constructor(private http : HttpClient) {
...
}
Run Code Online (Sandbox Code Playgroud)
如果没有实例化并作为 httpClient 的参数传递:我自然会收到“app.module.ts 中的错误,预期 1 个参数”!通过实例化,我打破了角度建议。
编辑: 我忽略了指定我确实导入了 httpClientModule
当我使用 Angular HttpClient 发出 GET 请求时,我会得到一个可观察的数据并在 RxJS 运算符 mergeMap 中处理它。
现在,一次又一次地抛出 404,我想抓住它。最后,浏览器控制台中不应出现任何错误消息,并且应使用流的下一个值来处理管道。
有这种可能吗?我没有用catchError()来管理它。
这是我的代码的简化版本:
...
this.service1.getSomeStuff().pipe(
mergeMap((someStuff) => {
return from(stuff);
}),
mergeMap((stuff) => {
return this.service2.getMoreStuff(stuff.id); // Here I need some error handling, if 404 occurs
}),
mergeMap((things) => {
return from(things).pipe(
mergeMap((thing) => {
if (allLocations.some(x => x.id === metaData.id)) {
return this.service2.getMore(thing.id, thing.type, thing.img_ref);
}
}),
map((thing) => {
...
Run Code Online (Sandbox Code Playgroud)
更新:添加了 catchError() 方法
我尝试了这种方式,但是没有检测到错误,并且下一个 mergeMap 不起作用(IDE 不再识别thing.id、thing.type、thing.img_ref等参数):
...
this.service1.getSomeStuff().pipe(
mergeMap((someStuff) => {
return from(stuff);
}), …Run Code Online (Sandbox Code Playgroud) 我面临 RxJS 的forkJoin运算符和 http 请求被 chrome 取消的问题。
我有一个名为 的可观察对象数组(即 http 请求)validationSupportBatch$。
我按如下方式使用该数组:
this.subscription.add(
forkJoin<T>(validationSupportBatch$)
.pipe(mergeMap(() => this.getByStandardActivityCode()))
.subscribe((svs: T[]) => {
this.validationSupports = svs;
this.notificationService.success('SVS.SAVE.success');
},
error => this.notificationService.error('SVS.SAVE.failure')
)
);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这些请求被 Chrome 取消了(请参见下面的屏幕截图,了解一批 3 个 http 请求)。
有人可以帮忙吗?
编辑:
以下是请求标头:
Provisional headers are shown
Accept: application/json, text/plain, */*
Authorization: Bearer XXX
Content-Type: application/json
Origin: https://localhost:4200
Referer: https://localhost:4200/validation/applied/activity/HHN-KADJAR-A0000020/standard-validation-support?planId=HHN-KADJAR-I001
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
x-validation-context: APPLIED
x-validation-project-family: HHN …Run Code Online (Sandbox Code Playgroud) 我正在使用 HostListener 来检测用户何时重新加载或关闭浏览器窗口。目的是#1 检查当前用户是否拥有记录上的“正在编辑”锁,#2 如果是,则调用可观察对象来更新数据库。(注意:我已经使用 CanDeactivate 实现了用于导航离开组件的锁定系统。HostListener 的使用专门用于重新加载或关闭浏览器窗口)。
根据这个类似的问题,'window:unload'是一个仅同步事件,因此我无法在主机侦听器的主体中使用异步 API 调用。
然而,根据 Mozilla 的说法,所接受的解决方案XMLHttpRequest()正在被弃用。
注意:从 Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)、Blink 39.0 和 Edge 13 开始,主线程上的同步请求已被弃用,因为它们会对用户体验产生负面影响。
我需要一个更可靠的解决方案。有没有办法在 Angular 中发送同步 api 调用来解决这个限制?或者是否有另一种方法可以确保 API 调用在浏览器重新加载或关闭之前完成?
// @HostListener allows guard against browser refresh, close, etc.
@HostListener('window:unload', ['$event'])
beforeUnloadHander($event) {
// Check if Is Being Edited must be removed
if (this.mustReleaseIsBeingEdited()) {
this.updateIsBeingEditedSub = this.updateIsBeingEdited$(true).subscribe(result => {
return true;
}, err => { …Run Code Online (Sandbox Code Playgroud) 我正在开发一个 Angular 10 应用程序,该应用程序使用HttpInterceptor向所有响应添加特定标头。不幸的是,在尝试测试此拦截器时,我不断收到以下错误:
Error: Expected one matching request for criteria "Match by function: ", found none.
Run Code Online (Sandbox Code Playgroud)
或类似的变体:
Error: Expected one matching request for criteria "Match URL: /endpoint", found none.
Run Code Online (Sandbox Code Playgroud)
我的期望是这个测试会通过,但我现在不知道为什么它不起作用。
这是我的拦截器:
Error: Expected one matching request for criteria "Match by function: ", found none.
Run Code Online (Sandbox Code Playgroud)
这是我的测试:
Error: Expected one matching request for criteria "Match URL: /endpoint", found none.
Run Code Online (Sandbox Code Playgroud)
也就是说,可能值得指出的是,我尝试应用以下资源中的解决方案但无济于事(大多数似乎与我已经拥有的类似,而且许多似乎适用于旧版本的 Angular):
HttpClient我所知道的。testing typescript angular angular-httpclient angular-httpclient-interceptors
在将数据发送到客户端之前,我已经阅读了十几篇关于如何在ArrayBuffertoBlob或 to之间转换的帖子Uint8Array......但我似乎根本无法让它工作。Blob当我确实获取数据时,在将其输出到文件之前,我无法将它们重建回来。
const Blob = require('cross-blob');
const randomBytes = require('randombytes');
const buffer = randomBytes(1024); // Supposed to give me Buffer
Run Code Online (Sandbox Code Playgroud)
以下是我尝试过的东西......
data = buffer;
Run Code Online (Sandbox Code Playgroud)
^ 给我<Buffer 11 22 33 ...>
data = Uint8Array.from(buffer);
Run Code Online (Sandbox Code Playgroud)
^ 给了我一个整数数组,这看起来最有前途?但是当到达客户端时,它变成了一个带有索引和字节值的对象......
data = Uint8Array.from(buffer).buffer;
Run Code Online (Sandbox Code Playgroud)
^ 给出ArrayBuffer { byteLength: 1024},当检查时它显示size: 2并且type: 'text/plain'......
data = new Blob(buffer, { type: 'application/octet-stream' });
data = new Blob([new Uint8Array(buffer, buffer.byteOffset, buffer.length)], { type: 'application/octet-stream' });
data …Run Code Online (Sandbox Code Playgroud) 使用 Angular 的 HTTP 客户端时,我们如何设置 Referrer-Policy HTTP 标头?
我尝试在下面设置它,但它不起作用:
let headers = new HttpHeaders();
headers = headers.set('Referrer-Policy', 'no-referrer');
this.httpClient.get(url, { headers: headers };
Run Code Online (Sandbox Code Playgroud)
在浏览器的“网络”选项卡中的 HTTP 请求信息中:
预期的:
Referrer Policy: no-referrer
Run Code Online (Sandbox Code Playgroud)
实际的:
Referrer Policy: origin-when-cross-origin
Run Code Online (Sandbox Code Playgroud) httprequest referrer angular angular-httpclient referrer-policy
我已经升级,从角4.2应用5,但更改后Http到HttpClient了对POST请求的错误:
错误,服务器响应状态为415(不支持的媒体类型)
在app.module我已经导入HttpClientModule:
import { HttpClientModule } from '@angular/common/http';
Run Code Online (Sandbox Code Playgroud)
旧代码:
post(url: string, model: any): Observable<any> {
let body = JSON.stringify(model);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this._http.post(url, body, options)
.map((response: Response) => <any>response.json())
.catch(this.handleError);
}
Run Code Online (Sandbox Code Playgroud)
新代码:
put(url: string, id: number, model: any): Observable<any> {
let body = JSON.stringify(model);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options: any = new …Run Code Online (Sandbox Code Playgroud) 我使用这个工具根据我的模型生成了我的实体组件和服务.
一切正常,但我在尝试在API中记录用户时遇到了问题(功能正常).
http.post()方法未被触发.我对角度很新,也无法弄清楚我做错了什么.
任何帮助都会很棒!
这是我的UserService的登录方法(该方法被正确调用,它只是http.post()不起作用):
/**
* Log a user by its credentials.
*/
login(username : string, password : string) : Observable<NmUser> {
let body = JSON.stringify({
'username': username,
'password': password
});
console.log(body);
return this.http.post(this.userUrl + 'login', body, httpOptions)
.pipe(
map(response => new NmUser(response)),
catchError(this.handleError)
);
} // sample method from angular doc
private handleError (error: HttpErrorResponse) {
// TODO: seems we cannot use messageService from here...
let errMsg = (error.message) ? error.message : 'Server error';
console.error(errMsg);
if …Run Code Online (Sandbox Code Playgroud) angular ×10
rxjs ×3
angular-httpclient-interceptors ×1
angular6 ×1
blob ×1
express ×1
http ×1
httprequest ×1
ngrx ×1
ngrx-effects ×1
node.js ×1
observable ×1
referrer ×1
subscription ×1
synchronous ×1
testing ×1
typescript ×1