在 Angular 6 中将 CORS 标头添加到响应中
Posted
技术标签:
【中文标题】在 Angular 6 中将 CORS 标头添加到响应中【英文标题】:Add CORS header to response in Angular 6 【发布时间】:2019-05-05 14:37:03 【问题描述】:我正在尝试从 Angular 6 中的后端服务器获取一些数据,以便以我自己的方式对其进行可视化。我已经准备了一个有效的 GET 请求,它可以对我需要的所有数据做出正确的响应,但问题是当它以典型方式使用时,例如在“普通”浏览器中,我收到了 CORS 错误 -标题丢失。那么即使有这个问题,我如何获取数据呢?通常,您必须在服务器端允许它,但这种情况有点不同。我已经安装了一个 Chrome 插件来为每个请求添加标题。有了这个插件,CORS 问题就不复存在了。
所以我的问题是,如何(以及是否)将我的 Angular 代码中的 CORS 标头添加到响应中,这样我就不必使用任何插件,并且该应用程序可以在每个浏览器上运行?
另外,为了防止任何 cmets,我获得的所有数据都是我可以合法访问的,它们是我自己的,我只是在 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'
);
我写的拦截器类:
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
中使用它,就像在 @987654322 中使用它一样@。不过,我仍然缺少一些东西。
【问题讨论】:
【参考方案1】:它不是那样工作的。 Cors 是在服务器端处理的东西。服务器管理员设置这些标头并允许某些域的位置。您应该适当地查看JsonP,或者如果您像您所说的那样控制数据,请查看允许您的域在您的服务器上。这些是Acces Control Allow Headers
【讨论】:
我知道 CORS 是什么以及它是如何工作的,但我想知道我是否可以使用 Angular 实现与 Chrome 插件相同的效果,它仍然允许我通过添加标题来查看数据。 这个类似的帖子可能会有所帮助:***.com/questions/36250615/cors-with-postman 是的。所以目前看来,Angular 无法做到这一点,因为我必须修改 Web 浏览器的行为,而 Web 应用程序无法做到这一点...... @Jack_Russell 浏览器负责限制 Web 应用访问跨域服务器。只有通过安装插件,您才能更改此行为。不允许网络应用程序更改这一点,因为如果可以,那么拥有 CORS 将毫无意义。【参考方案2】:当您在向服务器发出的跨源 http 请求中包含某些标头(例如 Authorization)时,浏览器通常会发出 OPTIONS(pre flight >) 向服务器请求允许的 Access-Control-Allow-Methods 和允许的 Access-Control-Allow-Headers,您的服务器端代码应使用这些响应浏览器实际发出您想要的 http 请求
【讨论】:
【参考方案3】:您不需要为请求设置标头。为了避免 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": "/"
只需稍加修改即可更改服务命令:
ng serve --proxy-config proxy.conf.json --port 55055 --host 0.0.0.0
现在对后端的请求将来自相同的角度域,不会再有 CORS 错误
注意:此代理配置仅用于开发目的。对于生产环境你应该在 webservers 中配置。
【讨论】:
问题是,REST API 所在的地址是远程的。我也尝试通过 nginx 代理请求,但我对此完全陌生。由于邮递员请求有效,我想知道是否有办法从我的应用程序发送请求,就好像它是邮递员请求一样,但是这里有些东西不正确,现在我完全迷路了以上是关于在 Angular 6 中将 CORS 标头添加到响应中的主要内容,如果未能解决你的问题,请参考以下文章