我的API服务器在Lumen框架上运行,并且我在那里安装了CORS中间件,并带有管理JSON POST数据的中间件。在服务器端,一切都很完美。
现在,对于UI,我将Angular 9与Material布局一起使用。我有一个非常简单的login组件:它基本上验证输入,然后调用与我的API服务器通信的服务AuthService。
AuthService非常简单:
import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { BehaviorSubject, Observable, throwError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { HttpClient, HttpHeaders, HttpErrorResponse, HttpParams } from '@angular/common/http'; export interface Token { token: string; token_type: string; expires_in: number; } @Injectable({ providedIn: 'root' }) export class AuthService { public isAuthenticated = new BehaviorSubject<boolean>(false); constructor( private http: HttpClient, private router: Router ) {} async checkAuthenticated() { const authToken = localStorage.getItem('access_token'); return (authToken !== null); } getToken() { return localStorage.getItem('access_token'); } async login(username: string, password: string) { const api = 'http://api.elektron.test/v1/login'; const headers = new HttpHeaders({'Content-Type': 'application/json; charset=UTF-8'}); const body = JSON.stringify({ email: username, password }); // tslint:disable-next-line:max-line-length return this.http.post(api, body) .subscribe((res: any) => { if(res.token) { this.isAuthenticated.next(true); localStorage.setItem('access_token', res.token); } }, error => { console.error(error); }, () => { console.log('etstamente'); }); } async logout(redirect: string) { const removeToken = localStorage.removeItem('access_token'); if (removeToken == null) { this.isAuthenticated.next(false); this.router.navigate([redirect]); } } handleError(error: HttpErrorResponse) { let msg = ''; if (error.error instanceof ErrorEvent) { // client-side error msg = error.error.message; } else { // server-side error msg = `Error Code: ${error.status}\nMessage: ${error.message}`; } return throwError(msg); } }
在
this.http.post
中,我可以在第三个参数中传递其他标头,并且我已经尝试过了,但是我面临的问题是,无论我传递给它的标头是什么,当我调用该请求时,Content-Type
永远不会发送。
我尝试过的另一个想法是使用拦截器:
import {HttpInterceptor, HttpRequest, HttpHandler, HttpHeaders} from '@angular/common/http'; import { AuthService } from './auth.service'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private authService: AuthService) { } intercept(req: HttpRequest<any>, next: HttpHandler) { const token = this.authService.getToken(); req = req.clone({ responseType: 'json' }); if (token) { req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) }); } if (!req.headers.has('Content-Type')) { req = req.clone({ setHeaders: { 'Content-Type': 'application/json', } }); } // setting the accept header req = req.clone({ headers: req.headers.set('Accept', 'application/json') }); return next.handle(req); } }
[到达那里的任何
req.clone
语句时,我的行为最终都与以前对POST
请求的解释相同。
所以,我不知道我在这里做错了什么或造成了什么。在Chrome浏览器中,当我尝试查看请求标头时,在“网络”选项卡下的控制台中,当应用了上述情况时,它显示显示了临时标头
-并且我在该问题上找到了一些堆栈溢出的答案,但是他们都没有解决我的问题。我花了最后5-6个小时在网上搜索解决方案,尝试了一些想法,但都无济于事。
EDIT:
此问题与Angular无关,但与服务器和后端配置以及处理preflight要求有关。我的API服务器在Lumen框架上运行,并且我在那里安装了CORS中间件,并带有管理JSON POST数据的中间件。在服务器端,一切都很完美。现在,对于...
这可能是问题req = req.clone({responseType:'json'});
经过一夜的不眠,我终于解决了这个问题,这不是Angular或其中的代码的问题,而是Web服务器的配置。