justine
justine

Reputation: 67

AngularJS and Symfony 3 CORS issue with Chrome

I've been struggling this last week with a bug on my backend and frontend.

I've made a REST API (php/symfony) to manage books and authors. I had an issue on cross-origin requests on the DELETE and it has been fixed since. And now I have an issue on the PUT (POST too) and this ONLY on Chrome (v62.0.3202.94). Tried my API on postman and it's working just fine, tested on Edge and Firefox too. I've tried to use the Allow-Control-Allow-Origin: * plugin for Chrome and didn't work either. Everytime i got the same error :

Request URL:http://127.0.0.1/whereIsMyBook-symfony/web/app_dev.php/updateAuthor/7
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Remote Address:127.0.0.1:80
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Access-Control-Allow-Origin:*
Allow:PUT
Cache-Control:no-cache, private
Connection:Keep-Alive
Content-Type:text/html; charset=UTF-8
Date:Tue, 05 Dec 2017 18:05:06 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.4.27 (Win64) PHP/5.6.31
Transfer-Encoding:chunked
X-Debug-Token:e8abc7
X-Debug-Token-Link:http://127.0.0.1/whereIsMyBook-symfony/web/app_dev.php/_profiler/e8abc7
X-Powered-By:PHP/5.6.31
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers:access-control-allow-origin,content-type
Access-Control-Request-Method:OPTIONS
Connection:keep-alive
Host:127.0.0.1
Origin:http://localhost:8000
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36

And an exception is thrown by my backend :

angular.js:12265 OPTIONS http://127.0.0.1/whereIsMyBook-symfony/web/app_dev.php/updateAuthor/7 net::ERR_ABORTED

I've tried to modify my app.config.js and adding the lines below :

['$httpProvider', function ($httpProvider) {
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
    $httpProvider.defaults.headers.post['Accept'] = 'application/json, text/javascript';
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
    $httpProvider.defaults.useXDomain = true;
}]

I think i have an issue with the pre-flight requests but can't seem to get rid of them correctly. I've browsed a lot of pages and still can't find why it's not working. As Leia once said : "You're my last hope".

Here's my method (in the service) :

this.editAuthor= function(formData, index){
         return $http({
            method : 'PUT',
            url : baseUrl + '/updateAuthor/' + index,
            data : formData,
            headers: {
                'Access-Control-Allow-Origin' : '*',
                'Content-Type': 'application/json'
            }
        })
    }

My API is hosted on wamp on localhost with the apache headers_module activated.

Thank you for your kind help

Upvotes: 1

Views: 1038

Answers (2)

Mcsky
Mcsky

Reputation: 1445

You are using angular, this framework use HTTP OPTIONS request to ask the server the authorized HTTP verbs in your backend application.

We can see some usefull informations to debug your error from the server's response

  • Status Code:405 Method Not Allowed, this HTTP error code is returned by the backend (Symfony here) when he can't handle the request on this route
  • Allow:PUT, The server return the verb which it can handle

After installation of NelmioCorsBundle add this configuration to your app/config/config.yml file.

nelmio_cors:
        paths:
            '^/api/':
                allow_origin: ['*']
                allow_headers: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
                max_age: 0

I advice you to define a base route to your symfony's api application, like /api and not just only /update

Let me know if something isn't clear :)

Upvotes: 1

Naoufel Raouine
Naoufel Raouine

Reputation: 1

You have to add to your controller API in Symfony this code:

        $jsonContent='{"products":[{"id":1,"nom":"aza","prix":5}]}';
        $response = new Response($jsonContent);
        // $response->headers->set('Content-Type', 'application/json');
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, 
        PUT, PATCH, DELETE');
        $response->headers->set('Access-Control-Allow-Headers' , 'Content-Type');

        return $response;

Upvotes: 0

Related Questions