简体   繁体   中英

Keystone JS CORS

Ok so I am pretty new to Keystone JS and I have decided to use it as an API backend for a project.

I have gotten all my API endpoints/routes are all done and they work perfectly in my browser however when trying to fetch the data remotely I keep getting the same error: XMLHttpRequest cannot load http://localhost:3000/keystone/api/ . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ' http://localhost ' is therefore not allowed access.

I am not unfamiliar with CORS and have tried to enable it by adding the following to my keystone.js and routes/index.js

keystone.js:

keystone.set('cors allow origin', true);
keystone.set('cors allow methods', true);
keystone.set('cors allow headers', true);

routes/index.js:

// Setup Route Bindings
exports = module.exports = function (app) {
    app.all('/api/*', keystone.middleware.cors);
    app.options('/api*', function(req, res) { res.send(200); });

    // Views
    app.get('/', routes.views.index);

    // API
    // Lists
    ...

Now I have tried finding solutions to this by looking through alot of documentation but according to my findings this should be more than enough to make CORS work with Keystone.

In addition to this I will present also my Keystone Service in my Angular JS 1.x frontend for you to see what I am trying to pull off..

keystone.service.js:

(function() {
    'use strict';

    angular.module('zApp')
        .service('KeystoneService', ['$log', '$http', function($log, $http) {
            var $keystoneApi = {};

            var _handleRequest = function(requestObj) {
                var data = {};

                if(requestObj.withCredentials === undefined) {
                    requestObj.withCredentials = true;
                }

                if(requestObj.method === undefined) {
                    requestObj.method = 'GET';
                }

                $http(requestObj, {headers: $keystoneApi.headers})
                    .then(
                        function success(response) {
                            data = response.data;
                        },
                        function error(response) {
                            // todo; handle error
                            $log.info(response);
                        }
                    );
                return data;
            };

            var _isIdValid = function(id) {
                if(/^[a-zA-Z0-9]*$/.test(id)) {
                    return true;
                }
                return false;
            };

            // Should be changed to oauth when there is better support in Keystone!
            this.init = function(settings) {
                if(settings.url !== undefined && settings.usr !== undefined && settings.pass !== undefined) {
                    $keystoneApi = settings;
                    $keystoneApi.auth = window.btoa($keystoneApi.usr + ':' + $keystoneApi.pass);
                    $keystoneApi.headers = {"Authorization": "Basic " + $keystoneApi.auth};
                    return this;
                }
                return false;
            }

            /**
             * User
             */
            this.getCmsAllUsers = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'User/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.getCmsUser = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'User/' + id
                    };

                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            this.updateCmsUser = function(userObject) {
                if(_isIdValid(userObject.id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'User/' + id + '/update/',
                        data: userObject
                    };

                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            /**
             * Profile
             */
            this.getCmsAllProfiles = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'Profile/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.getCmsProfile = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'Profile/' + id
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            this.createCmsProfile = function(profileObject) {
                var requestObj = {
                    url: $keystoneApi.url + 'Profile/create',
                    data: profileObject
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.updateCmsProfile = function(profileObject) {
                if(_isIdValid(profileObject.id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'Profile/' + profileObject.id + '/update',
                        data: profileObject
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            this.deleteCmsProfile = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'Profile/' + id + '/remove'
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            /**
             * Favourite Template
             */
            this.getCmsAllFavouriteTemplates = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'FavouriteTemplate/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.getCmsFavouriteTemplate = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'FavouriteTemplate/' + id
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            this.createCmsFavouriteTemplate = function(favouriteTemplateObject) {
                var requestObj = {
                    url: $keystoneApi.url + 'FavouriteTemplate/create',
                    data: favouriteTemplateObject
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.updateCmsFavouriteTemplate = function(favouriteTemplateObject) {
                if(_isIdValid(favouriteTemplateObject.id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'FavouriteTemplate/' + favouriteTemplateObject.id + '/update',
                        data: favouriteTemplateObject
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            this.deleteCmsFavouriteTemplate = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'FavouriteTemplate/' + id + '/remove'
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            /**
             * Customer Content
             */
            this.getCmsAllCustomerContent = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'CustomerContent/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.getCmsCustomerContent = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'CustomerContent/' + id
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            /**
             * Frontpage Content
             */
            this.getCmsAllFrontpageContent = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'FrontpageContent/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.getCmsFrontpageContent = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'FrontpageContent/' + id
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            /**
             * Faq
             */
            this.getCmsAllFaq = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'Faq/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            /**
             * General Settings
             */
            this.getCmsAllGeneralSettings = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'GeneralSettings/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.getCmsGeneralSettings = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'GeneralSettings/' + id
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            this.updateCmsGeneralSettings = function(favouriteTemplateObject) {
                if(_isIdValid(favouriteTemplateObject.id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'GeneralSettings/' + favouriteTemplateObject.id + '/update',
                        data: favouriteTemplateObject
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };

            /**
             * Org Units
             */
            this.getCmsAllOrgUnits = function() {
                var requestObj = {
                    url: $keystoneApi.url + 'OrgUnit/'
                };
                var response = _handleRequest(requestObj);
                // todo; handle response
                $log.info(response);
            };

            this.getCmsOrgUnit = function(id) {
                if(_isIdValid(id)) {
                    var requestObj = {
                        url: $keystoneApi.url + 'OrgUnit/' + id
                    };
                    var response = _handleRequest(requestObj);
                    // todo; handle response
                    $log.info(response);
                }
            };
        }]);
})();

Yes I know there is currently logic missing in my end-point methods but it is besides the point at the moment since none of these return anything but the same CORS error. I am also just using Basic Authorisation during the test phase this will be replaced by proper OAuth middleware so please refrain from commenting on that, it is also besides the point.

Any helpful insight is much appreciated.

Well, that's the point of CORS, ie to make it possible to keep frontend and backend on separate servers.

In keystone.js:

keystone.set('cors allow origin', true);
keystone.set('cors allow methods', true);
keystone.set('cors allow headers', true);

In routes\\index.js: either:

app.get('/api/stuff', [keystone.middleware.api, keystone.middleware.cors], routes.api.workshop.getStuff);

or:

app.get('/api/stuff', keystone.middleware.cors, routes.api.workshop.getStuff);

and all the other routes accordingly. That's all that is necessary to enable CORS headers.

This resolved the issue for me

in your Keystone.js file

add this line of code

Keystone.init({
'cors allow origin': true,
'cors allow methods': true,
 'cors allow headers': true,
})

in index.js file

add this line of code

app.get('/api/stuff/', [keystone.middleware.api, keystone.middleware.cors], routes.api.stuff.list);

to all your api routes

OK so I got a pointer from a friend on this issue.

The reason why I kept getting problems was the way my frontend app was positioned on a separate server, I have moved my AngularJS to keystone/public/ and now I have access to the API.

Might be obvious but this had completely gone past me. Hope this can help someone struggling with the same issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM