I'm trying to fetch some data from a backend server in Angular 6 so I can visualize it in my own way. I've already prepared a working GET request that results in a proper response with all the data I need, but the problem is that when it's used in a typical way, e.g in "normal" browser, I'm getting the CORS error - header is missing. So how do I get the data even with this problem? Typically, you must allow it on the server side, but this situation is a bit different. I've installed a Chrome plugin to add the header to every request. With the plugin, the CORS problem is no more.
So my question is, how (and if) can I add the CORS header in my Angular code to the response, so I wouldn't have to use any plugins and the app would work on every browser?
Also, just to prevent any comments, all the data I'm getting I have legal access to, they're my own and I'm just learning new stuff in Angular. As far as I know, I should use interceptors, but I'm pretty sure I'm doing it wrong. Here's my code:
The http service method:
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'
}
);
}
The Interceptor class I wrote:
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;
})
);
}
}
This is the component.ts class:
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)}`);
});
}
}
I've tried to use the Interceptor the way under this link, using the app.module.ts. This totally broke my app because I'm getting the CORS error even with the CORS plugin turned on. The other examples of code I found over the internet used code like
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;
});
in the interceptor, but I'm guessing it's for older versions of Angular, I can't use the map
method this way, so I tried using it inside of pipe
like it was used in the documentation. There's still something I'm missing though.