我的代码具有Subject,当添加新值时会触发HTTP请求,该请求返回Observable。
我要处理两种不同的方式(使用相同的数据),这些数据并使用产生的Observables存储group和times作为价值摆在ngFor使用的async管道。
尽管这样做确实可行,但是HTTP请求被多次发送-我只希望每个订阅一次发送一次。
下面是一个最小的示例。
import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { ExampleService } from "../example.service";
import "rxjs/add/operator/switchMap";
@Component({
templateUrl: "./example.component.html",
styleUrls: ["./example.component.scss"]
})
export class ExampleComponent implements OnInit {
constructor(
private exampleService: ExampleService
) { }
ngOnInit() {
var selections = new Subject<string>();
var appointments = selections
// exampleService.getData returns an HTTP …Run Code Online (Sandbox Code Playgroud) 在服务器自动更新令牌的上下文中,我正在努力解决基本问题:从响应中获取头数据.
它似乎与CORS无关,因为我的Node/express allwos授权/ x-access-token并相应地响应(请参阅下面的网络选项卡screeencap).
我希望看到工作的第一步是简单地从响应中读取标题.请参阅我的代码,它是文档中的样板文件.获取"Content-Length"的事件返回null.
AUTH-service.ts
login(username:string, password:string):Observable<boolean>{
this.loggedIn = false;
return new Observable( (observer:Observer<boolean>) => {
const body = {user: username, pwd: password};
const url = this.config.API_ENDPOINT_PUBLIC_AUTH;
this.httpClient.post(url, body, {
responseType: 'text',
observe: "response"
}).first().subscribe(
(response:HttpResponse<string>) => {
// DEBUG
console.log(response.headers.get('Authorization'));
console.log(response.headers.get('X-Test-Header'));
console.log(response.headers.get('Content-length'));
this.token = response.headers.get('Authorization');
this.storeToken(this.token);
this.currentUser = username;
this.loggedIn = true;
this.authChanged$.next('auth');
observer.next(true);
},
(err) => observer.next(false),
() => {},
);
});
}
Run Code Online (Sandbox Code Playgroud)
控制台输出:
空值
空值
空值
将此与此请求的网络选项卡的内容进行比较:
不用说我的HttpInterceptor也不起作用 - 在响应中提供"Authorization"标头时,它将该值用作新标记.这样可以实现令牌的自动续订:
token.interceptor.ts
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> …Run Code Online (Sandbox Code Playgroud) 对于我的应用程序,我创建了以下内容HttpInterceptor.有没有办法从这里向请求订阅者返回更改的响应版本?
import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
@Injectable()
export class RequestInterceptor implements HttpInterceptor {
constructor(
private router: Router
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// any way to alter response that gets sent to the request subscriber?
}
}, (error: any) => …Run Code Online (Sandbox Code Playgroud) HttpClient的文档说明了关于不变性的以下内容:
存在拦截器来检查和改变传出请求和传入响应.但是,了解HttpRequest和HttpResponse类在很大程度上是不可变的可能会令人惊讶.
这是有原因的:因为app可能会重试请求,拦截器链可能会多次处理单个请求.如果请求是可变的,则重试的请求将与原始请求不同.不可变性确保拦截器在每次尝试时都看到相同的请求.
我发现很难理解这个解释.有人可以提供解释吗?
在 Angular 5 HttpClient 中,我可以通过这种方式设置 HttpParams()。
const body = new HttpParams()
.set('email', 'test@mail.com')
.set('password', 'pass');
Run Code Online (Sandbox Code Playgroud)
但是当我尝试以这种方式设置 HttpParams() 时。未设置值。
const paramsMap = new Map<any, any>();
paramsMap.set("email", "test@mail.com");
paramsMap.set("password", "pass");
paramsMap.forEach((value: any, key: any) => {
body.set(key, value);
});
Run Code Online (Sandbox Code Playgroud)
为什么它没有设置?我怎样才能以类似的方式做到这一点?
我有一个使用注册了HttpInterceptor的插件的应用程序。
现在,我需要创建自己的拦截器,该拦截器必须在其他拦截器之前运行,因为它将更改其他拦截器使用的localStorage中的某些值。
注册新的HttpInterceptor时如何影响执行顺序?
嗨,我在尝试让 httpClient 补丁请求发送内容类型为“multipart/form-data”的 FormData 时遇到问题。
我已经指定了标题,如图所示:
private httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'multipart/form-data', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache'
})
};Run Code Online (Sandbox Code Playgroud)
我执行以下操作以保存到 nodejs 服务器:
const formData: FormData = new FormData();
formData.append('materialFile', 'something');
return this.httpClient.patch<any>(this.apiUrl + loan.id, formData, this.httpOptions);Run Code Online (Sandbox Code Playgroud)
在我的 Nodejs/Express 服务器上,我执行以下操作:
const Multer = require('multer');
router.patch('/:id', Multer().fields([{ name: "materialFile", maxCount: 1 }]), (req, res, next) => {
console.log(req.files['materialFile']);
});Run Code Online (Sandbox Code Playgroud)
当我检查浏览器上的请求标头时,我看到内容类型是 application/json。
有谁知道为什么?
我有一个创建pdf报告并下载它的spring boot API,如果我直接在浏览器中调用API,则直接创建和下载pdf,但是当我从Angular 6调用GET API时,我收到以下错误:
Spring启动(java)代码:
@RequestMapping(value = "/app_report/en", method = RequestMethod.GET)
@ResponseBody
public void getEnRpt(HttpServletResponse response, @RequestParam("appNum") String appNum) throws JRException, IOException, SQLException {
JasperReport jasperReport = JasperCompileManager.compileReport("./src/main/resources/jasperReports/App_created_en.jrxml");
Connection connection = dataSource.getConnection();
Map<String, Object> params = new HashMap<>();
params.put("P_APP_NO", appNum);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, connection);
response.setContentType("application/x-pdf");
response.setHeader("Content-disposition", "inline; filename=App_report_en.pdf");
final OutputStream outStream = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, outStream);
}
Run Code Online (Sandbox Code Playgroud)
调用API的Angular代码:(我试过多种方式,这里显示了两个):
this.http.get(this.api_url + reportUrl, {
responseType: 'blob'
}, ).subscribe((response: File) => {
console.log('report is downloaded');
});
this.http.get(this.api_url + reportUrl).subscribe(
(response) => …Run Code Online (Sandbox Code Playgroud) 我需要从 Angular 5 中的服务类进行两个相关的 HTTP 调用并返回一个 Observable,以便我的组件可以订阅它。所以在服务类函数内部:
stringstring将被 HTTP 调用 2 用作输入string[]Observable<string[]>不工作的代码(错误:函数必须返回一个值):
getData(): Observable<string[]> {
this.httpClient.get<string>('service1/getData').subscribe(
dataFromSvc1 => {
return this.httpClient.get<string[]>('service2/getData/' + dataFromSvc1);
},
err => {
return throwError(err);
}
)
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 http 客户端上传文件,但我总是从后端得到不好的响应。我假设问题出在请求上,因为除此之外,我的请求所具有的一切都与我在 aurelia http 客户端上发出的请求完全相同。
一般来说,这里有一些关于 angular 请求标头的信息:
Request URL: https://*/document/document?name=ecv_template_en.pdf&classification=0
Request Method: POST
Content-Type: application/json
Request payload:
------WebKitFormBoundary1gYAP6XB8f1TQ7RP
Content-Disposition: form-data; name="blobFile"; filename="ecv_template_en.pdf"
Content-Type: application/pdf
------WebKitFormBoundary1gYAP6XB8f1TQ7RP--
Run Code Online (Sandbox Code Playgroud)
来自 aurelia http 客户端的相同请求:
Request URL: https://*/document/document?name=ecv_template_en.pdf&classification=0
Request Method: POST
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydb5u93415NsBfKEz
Run Code Online (Sandbox Code Playgroud)
现在没有请求有效负载,而是带有 blobFile: (binary)
这是我为了重现调用而执行的角度代码:
const formData = new FormData();
formData.append("blobFile", documentUpload.file);
return this.http
.post(`${*}/document?name=${name}&classification=${classification}`,
formData).pipe(
map(do stuff))
);
Run Code Online (Sandbox Code Playgroud)
我还检查了 formData 的内容,它在 aurelia 请求和角度请求上完全相同。
我正在调用的端点如下:
[HttpPost()]
public ActionResult Create([FromForm]IFormFile blobFile,
[FromQuery] string name,
[FromQuery] ClassificationType classification)
Run Code Online (Sandbox Code Playgroud) angular ×9
rxjs ×3
typescript ×3
angular5 ×1
angular6 ×1
express ×1
immutability ×1
javascript ×1
multer ×1