dandev91
dandev91

Reputation: 1731

Angular 2 + PHP: CORS preflight issues

I am new to using Angular 2 (and front end development in general), and I've hit a problem with CORS. Essentially, I have two HTTP servers running - one is my localhost on port 4200 (the Angular 2 CLI server which runs the application) and the other is a WAMP server on port 8080 which holds the PHP scripts I use to communicate to a remote SQL server.

My problem is that I keep getting CORS related errors when running my application. The latest error I am receiving is:

XMLHttpRequest cannot load http://localhost:8080/hvTool2_Ang2/src/app/php/pullData.php. Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

I have tried the following methods, as per other Stack Overflow questions and answers:

A. Added the following code to my http.conf for Apache (WAMP server) and then restarted the services.

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</IfModule>

B. I have added the following PHP code before my echo statement in PHP:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');

C. I know some people have suggested turning off Web Security Services in Chrome. I can do this, but I would rather see CORS implemented correctly.

I don't quite grasp what this preflight thing is. From what I have gathered, the CORS preflight is only sent on certain occassions (non-GET or non-POST HTTP requests or/and HTTP requests that have options defined [please correct me if I am wrong]). Also, I figure I am meant to reply to this CORS preflight with something - but I am unsure what.

This is my Angular 2 code:

getData(routing: string, functionindex: number, dataarray) {
    var sentData = JSON.stringify(dataarray);
    var sentArray = [routing, functionindex, sentData];
    var returnedJSON;
    var url;
    if (this.dev_env == true){
      url = this.devPHPfolderURL;
    }
    else{
      url = this.prodPHPfolderURL;
    }
    let headers = new Headers();
    //headers.append('Content-Type', 'application/json'); //CORS issue
    headers.append('Content-Type', 'text/plain'); //no CORS issue

    return this.http.post(url, sentArray)
        .subscribe(
            result => returnedJSON = result,
            () => console.log("Failed..."),
            () => console.log("Completed: " + returnedJSON)
        );
  }

This is the PHP function which executes the commands and echos the response: function queryDB($query){

$myServer = "SERVER"; //Actual variable answers were changed for this post.
$myUser = "USER";
$myPass = "PASS";
$myDB = "DATABASE"; 

// connection to the database
$connection = odbc_connect("Driver={SQL Server};Server=$myServer;Database=$myDB;", $myUser, $myPass) or die("Couldn't connect to SQL Server on $myServer");
$result = odbc_prepare($connection, $query);
odbc_execute($result)or die(odbc_error($connection));
odbc_close($connection);
odbc_fetch_array($result);

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');

while ($info = odbc_fetch_array($result)) {
   $total[] = $info;
}

echo json_encode(odbc_fetch_array($total); //To send to JavaScript

}

EDIT: Weirdly enough, when I use:

headers.append('Content-Type', 'text/plain');

No CORS issue occurs. But when I use:

headers.append('Content-Type', 'application/json');

A CORS issue occurs. I need to return a JSON object to JavaScript. What am I doing wrong?

Upvotes: 1

Views: 1961

Answers (1)

In the service of Angular use a different header:

this.reqOpts = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }};

this gonna works, but I can't understand why it is necessary in the client-side

Upvotes: 1

Related Questions