Saturday, May 26, 2018

has been blocked by CORS policy: No 'Access-Control-Allow-Origin'

Hi Guys,

This blog is about issues I have faced while fetching data from a REST Web Service.

When I try to get the data from the service I faced an error like ,

Failed to load http://localhost:8090/org.myProject/question: Redirect from 'http://localhost:8090/org.myProject/question' to 'http://localhost:8090/org.myProject/question/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
This is because the rest service does not provide the response for Http requests from a different domain . The solution to this is add some extra the configuration in the Service to accept requests from a different domains. Lets have a look at the code.
import { EventEmitter, Injectable } from '@angular/core';
import { Headers, Http ,Response} from '@angular/http';
import {  HttpClientModule } from '@angular/common/http';
import {  HttpModule } from '@angular/http';


import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class QuestionService{
constructor(private http:Http) {}
loadQuestions(){


return this.http.get('http://localhost:8090/org.myProject/question')
.map(
        (response: Response) => {
          const data = response.json();
       
          return data;
        }
      )
      .catch(
        (error: Response) => {
          return Observable.throw('Something went wrong');
        }
      );

}
}
That's the service,check out the  controller .
import { Component, OnInit } from '@angular/core';
import { QuestionService } from './question.service';


@Component({
  selector: 'app-question',
  templateUrl: './question.component.html',
  styleUrls: ['./question.component.css'],
  providers:[QuestionService]
})
export class QuestionComponent  {

  constructor(private questionService:QuestionService) { }




onGet() {

  this.questionService.loadQuestions().subscribe(
        (questions: any[]) => {this.questions = questions;console.log(questions);},
        (error) => console.log(error)
      );

  }

  var questions;
}

The component file is as below

<div class="container">
<div class="row">
<div>
Question:
<select id="question"  >
<option>Select</option>
<option *ngFor="let question of questions" ngValue="question">{{question.subjectDesc}}</option>
</select>
</div>
</div>
<div class="row">
<div>
 <button class="btn btn-primary" (click)="onGet()">Get Server Response </button>
</div>
</div>

</div>

The change actually has to be done on the server side code . I am using a Spring Web application at the back end . By default it does not respond other hosts. So , Lets add the following entries to web.xml .
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

Test once the service is deployed.

ec2-user@ec2 Permission denied