title: How to solve Cross-Origin-Request-Block issue while fetching data using angular2 and php?
body: <p>Please read the question in detail since it is a long one with various edits and extended updates as per the request of other users. </p>
  
  <p>I am trying to send data to php file using angular2. I am doing the angular project in Unix and the <code>var/www/html/</code> is the php Xampp folder locations for running the php files.</p>
  
  <p>My folder structure is like this:-</p>
  
  <pre><code>var/www/html/
          |_(angproject)
                  |_(phpscript)
                  |       |_login.php
                  |_(src)
                     |_(app)
                          |_(admin)
                          |   |_(login)
                          |   |   |_login.component.ts
                          |   |
                          |   |_admin.component.ts
                          |
                          |_(_admin_service)
                          |       |_admin.login.ts
                          |
                          |_(_animations)
                          |
                          |_(front)
                          |
                          |_(_models)
                          |   |_admin.model.ts
                          |
                          |_app.module.ts
  </code></pre>
  
  <p>My <strong>app.module.ts</strong> file is like this:-</p>
  
  <pre><code>import { HttpModule, Http, Response, Headers, RequestOptions} from '@angular/http';
  import { HttpClientModule } from '@angular/common/http';
  import { BrowserModule } from '@angular/platform-browser';
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
  import { NgModule } from '@angular/core';
  import { RouterModule, Routes } from '@angular/router';
  import { FormsModule } from '@angular/forms';
  import { APP_BASE_HREF } from '@angular/common';
  import { CanActivate } from "@angular/router";
  
  
  import { AppComponent } from './app.component';
  import { FrontComponent } from './front/front.component';
  import { AdminComponent } from './admin/admin.component';
  import { LoginComponent } from './admin/login/login.component';
  import { DashboardComponent } from './admin/dashboard/dashboard.component';
  import { HeaderComponent } from './admin/header/header.component';
  import { FooterComponent } from './admin/footer/footer.component';
  import { LeftmenuComponent } from './admin/leftmenu/leftmenu.component';
  import { NavbarComponent } from './admin/navbar/navbar.component';
  import { ShortcutbarComponent } from './admin/shortcutbar/shortcutbar.component';
  import { AdminLoginService } from './_admin_service/admin.login';
  
  const appRoutes: Routes = [
    { path: 'admin',
      component: AdminComponent,
      children: [
            { path: '', component: LoginComponent},
            { path: 'dashboard', component: DashboardComponent}
      ]
    }
  ];
  
  @NgModule({
    declarations: [
      AppComponent,
      FrontComponent,
      AdminComponent,
      LoginComponent,
      DashboardComponent,
      HeaderComponent,
      FooterComponent,
      LeftmenuComponent,
      NavbarComponent,
      ShortcutbarComponent
    ],
    imports: [
      HttpModule,
      HttpClientModule,
      BrowserModule,
      BrowserAnimationsModule,
      FormsModule,
      RouterModule.forRoot(
        appRoutes,
        { enableTracing: true } // &lt;-- debugging purposes only
      )
    ],
    providers: [{provide: APP_BASE_HREF, useValue : '/' },AdminLoginService],
    bootstrap: [AppComponent]
  })
  export class AppModule { }
  </code></pre>
  
  <p>My <strong>login.component.ts</strong> file is this:-</p>
  
  <pre><code>import { Component, OnInit, Input } from '@angular/core';
  import { Router, ActivatedRoute } from '@angular/router';
  
  import { fadeInAnimation } from '../../_animations/index';
  import { Admin } from '../../_models/admin.model';
  import { AdminLoginService } from '../../_admin_service/admin.login';
  
  @Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css'],
    animations: [fadeInAnimation],
    host: { '[@fadeInAnimation]': '' },
    providers: [AdminLoginService]
  })
  
  export class LoginComponent implements OnInit {
      loading = false;
      returnUrl: string;
      responseStatus:Object= [];
      status:boolean ;
      //@Input() admin:Admin;
  
     model = new Admin('', '', '', 'Emailsss','Passwordsss'); 
  
      constructor(
          private route: ActivatedRoute,
          private router: Router,
          private _adminLogin: AdminLoginService
      ){}
  
    submitPost()
    {        
        //console.log("submit Post click happend " + this.model.email)
        //console.log(this.model);
        this._adminLogin.postLogin(this.model).subscribe(
           data =&gt; console.log(this.responseStatus = data),
           err =&gt; console.log(err),
           () =&gt; console.log('Request Completed')
        ); 
        this.status = true;       
    }
  
      ngOnInit() {
  
      }
  }
  </code></pre>
  
  <p>The service file <strong>admin.login.ts</strong> file is this:-</p>
  
  <pre><code>import { Http, Response, Headers, RequestOptions} from '@angular/http';
  import { HttpHeaders } from '@angular/common/http';
  import { Injectable } from '@angular/core';
  import 'rxjs/add/operator/map';
  import { Admin } from '../_models/admin.model';
  
  @Injectable()
  export class AdminLoginService {
      http : Http;
      actionUrl : string;
      admin_login_Url: string;
      postData: Admin;
  
  
      constructor(public _http: Http) {
         this.http = _http;
         this.admin_login_Url = 'http://localhost/angproject/phpscript/login.php';
      }
      postLogin(postData:Admin) {
          let headers = new Headers();
          headers.append("Access-Control-Allow-Origin","*");
          headers.append("Access-Control-Allow-Methods","GET, POST");
          headers.append("Content-Type","application/json");
  
          let options = new RequestOptions({ headers: headers });
          console.log(postData);
  
          this.actionUrl = this.admin_login_Url;
          return this.http.post(this.actionUrl, {postData}, options)
            .map(res =&gt; res.json());          
      }
   }
  </code></pre>
  
  <p>And ultimately, my login.php file is this:-</p>
  
  <pre><code>&lt;?php
  header("Access-Control-Allow-Origin: *");
  header("Access-Control-Allow-Methods: GET, POST");
  header("Access-Control-Allow-Headers: *");
  header("Content-Type: application/json; charset=utf-8");
  include('connection.php');
  
  $rawData    = file_get_contents("php://input");
  $data       = json_decode($rawData, true);
  
  $error = array();
  if(isset($data['postData']['email']) &amp;&amp; !empty($data['postData']['email']))
      $email = $data['postData']['email'];
  else 
      $error[] = "Email was not entered";
  if(isset($data['postData']['password']) &amp;&amp; !empty($data['postData']['password']))
      $password = $data['postData']['password'];
  else 
      $error[] = "Password was not entered";
  
  if(empty($error))
  {
      $runQuery = "SELECT * FROM users WHERE email = '$email' AND password = '$password'";
      $result = $conn-&gt;query($runQuery);
      if ($result-&gt;num_rows &gt; 0) 
      {
          $response['status'] = 1;
          $response['message'] = "Login successfully";
          $response['error'] = 0;
      } 
      else 
      {
          $response['status'] = 0;
          $response['message'] = "An error occured while logging in";
          $response['error'] = $conn-&gt;error;
      }
  }
  else
  {
      $response['status'] = 0;
      $response['message'] = "Parameter missing";
      $response['error'] = $error;
  }
  $respond = json_encode($response);
  echo $respond;
  exit;
  ?&gt;
  </code></pre>
  
  <p>Now here is the problem. When testing in Chrome, clicking the submit button once is firing calling for the php script (Ajax) twice. The first call doesn't send any data and hence it shows validation message in return response. The second call sends the form's data and hence fetching the desired result by matching the data sent.</p>
  
  <p><a href="https://i.stack.imgur.com/FU7ed.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FU7ed.png" alt="enter image description here"></a></p>
  
  <p>In case of firefox, I am getting this response:-</p>
  
  <p><a href="https://i.stack.imgur.com/fhHqG.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fhHqG.png" alt="enter image description here"></a></p>
  
  <p><a href="https://i.stack.imgur.com/Kw7Sj.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Kw7Sj.png" alt="enter image description here"></a></p>
  
  <p>How can I solve it?</p>
  
  <p><strong>Note</strong>:</p>
  
  <p>Here are the Request Headers of the "<strong>first call</strong>" in chrome:</p>
  
  <p><a href="https://i.stack.imgur.com/f9IbX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/f9IbX.png" alt="enter image description here"></a>
  <a href="https://i.stack.imgur.com/UPMiG.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UPMiG.png" alt="enter image description here"></a></p>
  
  <p>Here are the Request Headers of the "<strong>second call</strong>" in chrome:
  <a href="https://i.stack.imgur.com/i5Wac.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/i5Wac.png" alt="enter image description here"></a>
  <a href="https://i.stack.imgur.com/6Bmcr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6Bmcr.png" alt="enter image description here"></a></p>
  
  <p><strong>EDIT: Dated- 04-04-2018</strong>:</p>
  
  <p>As per the suggestions from <strong>David</strong>, I made subsequent changes in my login.php file:</p>
  
  <pre><code>header("Access-Control-Allow-Origin: http://localhost:4200");
  header("Access-Control-Allow-Headers: application/x-www-form-urlencoded");
  header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
  </code></pre>
  
  <p>In the admin.login.ts file, I made the following changes:-</p>
  
  <pre><code>postLogin(postData:Admin) {
    let headers = new Headers();
    headers.append("Accept", "q=0.8;application/json;q=0.9");
    this.actionUrl = this.admin_login_Url;
    return this.http.post(this.actionUrl, {postData}, { headers: headers })
            .map(res =&gt; res.json()).share();
      }
  }
  </code></pre>
  
  <p><strong>Question 1:</strong>
  For the above code, I took reference from this <a href="https://hassantariqblog.wordpress.com/2016/12/03/angular2-error-in-firefox-exception-syntaxerror-json-parse-unexpected-character-of-the-json-data/" rel="nofollow noreferrer">site</a>. Yet, I am still getting the error. How can I fix this in Firefox?</p>
  
  <p>In the above code, I added the line <code>headers.append("Accept", "q=0.8;application/json;q=0.9");</code> to overcome an error shown below:-</p>
  
  <p><a href="https://i.stack.imgur.com/bynHV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bynHV.png" alt="enter image description here"></a></p>
  
  <p>How can I overcome this problem?</p>
  
  <p><strong>Question 2:</strong></p>
  
  <p>In Firefox, the console reads: </p>
  
  <pre><code>Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/angproject/phpscript/register.php. (Reason: invalid token ‘application/x-www-form-urlencoded’ in CORS header ‘Access-Control-Allow-Headers’).
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/O4qBa.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/O4qBa.png" alt="enter image description here"></a></p>
  
  <p>When checking in Chrome, I can see two calls in the network tab in console. The first call's request type is OPTIONS, while the second call has request type as POST.</p>
  
  <p>In case of Firefox, I am getting only one call with request type OPTIONS. The POST request isn't taking place at all.</p>
  
  <p><a href="https://i.stack.imgur.com/rKnpT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/rKnpT.png" alt="enter image description here"></a></p>
  
  <p>How can I fix this?</p>