Search code examples
imagesymfonycorssymfony3

CORS error when i try to get images on Symfony 3


I've an issue on my project, i have a cordova app on tablet that need to retrieve image from an api, my api is on symfony 3 and have Nelmio CORS Bundle installed and configured, standart get request work and i have the 'Cross-origin-allow' on header but when i try to get image network say me "CORS Error: MissingAllowOriginHeader".

my bundle config:

nelmio_cors:
    defaults:
        allow_credentials: false
        allow_origin: []
        allow_headers: []
        allow_methods: []
        expose_headers: []
        max_age: 0
        hosts: []
    paths:
        '^/medias/':
            allow_origin: ['*']
            allow_headers: ['*']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
            max_age: 3600
        '^/api/':
            allow_origin: ['*']
            allow_headers: ['*']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
            max_age: 3600

and my code that retrieve image:

const prom = axios({method: "get", url: encodeURI(element.url), responseType: responseType}).then((response) => {
                if (process.env.cordova)
                    createFile(element.id, extension, response.data);
                else
                    response.data.pipe(fs.createWriteStream("./server/public/" + path));
            }).catch((error) => {console.log("IMG DL ERROR FOR " + element.id + " : " + error)});

element is an array that contain image url, type and extension.

this is an exemple of url that work :

https://www.#######.com/api/updates/15151

And this one don't work:

https://#######.com/medias/images/item/4146/andalouse.jpg


Solution

  • Nelmio CORS Bundle provides an easy way to control CORS, in this case is missing the node origin_regex.

    nelmio_cors:
        defaults:
            allow_credentials: false
            allow_origin: []
            allow_headers: []
            allow_methods: []
            expose_headers: []
            max_age: 0
            hosts: []
        paths:
            '^/medias/':
                origin_regex: true
                allow_origin: ['*']
                allow_headers: ['*']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
                max_age: 3600
            '^/api/':
                origin_regex: true
                allow_origin: ['*']
                allow_headers: ['*']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
                max_age: 3600
    

    Well, now let's talk about allow_origin: ['*'] if you use this configuration, you don't need nemio in your project, in this case, you can change for this on the nemio_cors.yml file with your productions url and be override on your dev local env:

    nemio.yml

    nelmio_cors:
        defaults:
            allow_credentials: false
            allow_origin: []
            allow_headers: []
            allow_methods: []
            expose_headers: []
            max_age: 0
            hosts: []
        paths:
            '^/medias/':
                origin_regex: true
                allow_origin: ['^http://www.#######.com', '^http://#######.com']
                allow_headers: ['*']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
                max_age: 3600
            '^/api/':
                origin_regex: true
                allow_origin: ['^http://www.#######.com', '^http://#######.com']
                allow_headers: ['*']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
                max_age: 3600
    

    dev/nemio.yml

    nelmio_cors:
        paths:
            '^/medias/':
                allow_origin: ['*']
            '^/api/':
                allow_origin: ['*']
    

    another solution is add an env parameter with the list of the origins, like nemio on SF 5 does.

    nelmio_cors:
        defaults:
            origin_regex: true
            allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
            allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
            allow_headers: ['Content-Type', 'Authorization']
            expose_headers: ['Link']
            max_age: 3600