1

I've got a very strange issue.

  • local hosted PHP Slim App using XAMPP (localhost:4040)
  • local hosted Angular 4 App using CLI (localhost:4200)

Making API Requests using "Postman" and browser is no problem, everything works fine. Now I'm integrating the requests into my Angular app using import { Headers, Http } from '@angular/http'; and observables.

     const requestUrl = 'http://localhost:4040/register';
     const headers = new Headers({
        'content-type': 'application/x-www-form-urlencoded'
     });

     this.http
        .get(requestUrl, {headers: headers})
        .map(response => response.json())
        .subscribe(result => {
           console.log(result);
        }, error => {
           console.log(error);
        });

The request always fails with:

Failed to load http://localhost:4040/register: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.

But: I am definitely sending these headers!

    public static function createJsonResponseWithHeaders($response, $requestedData)
{
    // Add origin header
    $response = $response->withHeader('Access-Control-Allow-Origin', '*');
    $response = $response->withHeader('Access-Control-Allow-Methods', 'GET');

    // Add json response and gzip compression header to response and compress content
    $response = $response->withHeader('Content-type', 'application/json; charset=utf-8');
    $response = $response->withHeader('Content-Encoding', 'gzip');

    $requestedData = json_encode($requestedData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
    $response->getBody()->write(gzencode($requestedData), 9);

    if (!$requestedData || (count($requestedData) === 0)) {
        return $response->withStatus(404)->write('Requested data not found or empty! ErrorCode: 011017');
    }

    return $response;
}

What I already tried for solving:

  • Run Slim App inside a Docker Container to get a different origin than localhost - same behaviour

  • Add allow-origin-header right on top of the index.php
    header('Access-Control-Allow-Origin: *'); - same behaviour

btx
  • 1,972
  • 3
  • 24
  • 36

2 Answers2

1

Your requests are blocked because of CORS not being set up properly. There are other questions that address this, e.g. How to make CORS enabled requests in Angular 2

What you should ideally look at using is a proxy that forwards your requests to the API, the latest Angular CLI comes with support for a dev proxy (see https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md) out of the box. You set it up with a proxy.conf.json that could look like this:

{ "/api": { "target": "http://localhost:4040", "secure": false, "pathRewrite": {"^/api" : ""} } }

What this piece of code does is any requests from Angular to a URI matching /api will be forwarded to localhost:4040.

Note that you will also need to figure out how your app will talk to the API server in a non-dev environment. I have been happy with using Nginx to serve Angular files, and act as proxy for the API.

CubaLibre
  • 1,675
  • 13
  • 22
0

Sorry, my bad. The solution is simple:

The "Cache-control" header in the request seems to be not allowed, although it worked fine when testing the api with Postman. I removed the header from the request and everything worked well.

btx
  • 1,972
  • 3
  • 24
  • 36