我正在尝试从Angular 6的后端服务器中获取一些数据,以便可以用自己的方式可视化它们。我已经准备好一个有效的GET请求,可以对我需要的所有数据进行正确的响应,但是问题是,当以一种典型的方式(例如在“正常”浏览器中)使用它时,出现了CORS错误-标头丢失。那么,即使有这个问题,我如何获得数据呢?通常,必须在服务器端允许它,但是这种情况有些不同。我已经安装了Chrome插件,将标头添加到每个请求中。有了该插件,CORS问题就不再存在。
所以我的问题是,如何(以及是否)可以在Angular代码中将CORS标头添加到响应中,这样我就不必使用任何插件,并且该应用程序可以在每种浏览器上运行?
此外,为了防止发表任何评论,我所获得的所有数据我都有合法的访问权限,它们是我自己的,我只是在学习Angular中的新知识。据我所知,我应该使用拦截器,但是我敢肯定我做错了。这是我的代码:
http服务方法:
getFullResponse(domain: string, projectName: string, credentials: Credentials) {
console.log('RequestService method getIssuesForProject() fired');
return this.http.get('https://' + domain + '.myserver.local/api/' + projectName,
{
headers: new HttpHeaders({'Authorization': 'Basic ' + btoa(credentials.username + ':' + credentials.password)}),
observe: 'response'
}
);
}
我写的Interceptor类:
import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
@Injectable()
export class ResponseInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
map(event => {
if (event instanceof HttpResponse) {
event = event.clone({
headers: event.headers.set('Access-Control-Allow-Origin', '*')
});
}
return event;
})
);
}
}
这是component.ts类:
import {Component, OnInit} from '@angular/core';
import {RequestService} from '../../shared/service/RequestService.service';
import {Credentials} from '../../shared/model/credentials';
@Component({
selector: 'app-project',
templateUrl: './project.component.html',
styleUrls: ['./project.component.css']
})
export class ProjectComponent implements OnInit {
projectKey = '';
headers;
credentials: Credentials;
constructor(private reqService: RequestService) {
}
ngOnInit() {
}
onSubmit(domainName: string, projectKey: string, user: string, password: string) {
this.projectKey = projectKey;
this.credentials = {
username: user,
password: password
};
this.reqService.getFullResponse(domainName, projectKey, this.credentials)
.subscribe(resp => {
const keys = resp.headers.keys();
this.headers = keys.map(key => `${key}: ${resp.headers.get(key)}`);
});
}
}
我尝试使用app.module.ts在此link下使用拦截器。这完全破坏了我的应用程序,因为即使打开了CORS插件,我也收到了CORS错误。我在互联网上找到的其他代码示例使用的代码是
return next.handle(reqClone)
.map(event => {
if (event instanceof HttpResponse) {
event = event.clone({
headers: event.headers.set('x-test-res', 'res-test-header')
});
}
return event;
});
在拦截器中,但是我猜它是针对较旧版本的Angular,我不能以这种方式使用map
方法,所以我尝试像在使用时那样在pipe
内部使用它在documentation中。我仍然缺少一些东西。
答案 0 :(得分:1)
它不能那样工作。 Cors是在服务器端处理的东西。 Serveradministrator设置这些标头并允许某些域的位置。您应该考虑使用JsonP,或者如果您说过要控制数据,则可以考虑允许服务器上的域。这些是Acces Control Allow Headers
答案 1 :(得分:0)
在向服务器发出的跨源HTTP请求中包含诸如 Authorization 之类的某些标头时,浏览器通常会进行 OPTIONS (飞行前 >)向服务器发出请求,要求提供允许的 Access-Control-Allow-Methods 和允许的 Access-Control-Allow-Headers ,您的服务器端代码应对此做出回应浏览器实际发出您想要的http请求
答案 2 :(得分:0)
您无需为请求设置标题。为了避免Angular中的 CORS错误,您应该出于开发目的而使用 proxy pass 配置。
在 package.json 附近添加一个名为 proxy.conf.json 的文件。从您的请求获取URL中添加 / proxy
this.http.get('/proxy/api/' +
projectName).subscribe(resData => {
console.log(resData);
});
在 proxy.conf.json 中将代理规则设置为
{
"/proxy/*": {
"target": "http://backendDomain:8080",
"secure": false,
"logLevel": "debug",
"changeOrigin": true,
"pathRewrite": {
"^/proxy": "/"
}
}
}
只需很少修改即可更改serve命令:
ng serve --proxy-config proxy.conf.json --port 55055 --host 0.0.0.0
现在,对后端的请求将来自相同的角度域,并且不会再出现 CORS 错误
注意:此Proxy配置仅用于开发目的。对于生产环境,应该在Web服务器中进行配置。