How to set AngularjJS base URL dynamically based on fetched environment variable?

后端 未结 4 1142
耶瑟儿~
耶瑟儿~ 2020-12-10 05:18

I have a development and production environment in which my URL\'s differ:

production:

www.exmaple.com/page

development:

d

相关标签:
4条回答
  • 2020-12-10 05:39

    I personnaly do this kind of stuff with grunt.

    When I run my angular-app I have multiple tasks :

    > grunt run --target=dev
    > grunt run --target=prod
    > grunt build --target=dev
    > grunt build --target=prod
    > etc...
    

    Then grunt do strings replacement with the help of the grunt-preprocess module :

    my constants.tpl.js file gets parsed :

    [...]
    baseUrl:           '/* @echo ENV_WS_URL */',
    [...]
    

    and the url is populated.

    There are endless possibilities (string replacements, file copy, etc).

    Doing it with grunt ensure that dev config files do not go in production for example..

    I can put more details if you're interested but I only wanted to show you a different approach.

    edit gruntFile example :

    'use strict';
    
    module.exports = function(grunt) {
    
        /**
         * Retrieving current target
         */
        var target = grunt.option('target') || 'dev';
        var availableTargets = [
            'dev',
            'prod'
        ];
    
        /**
         * Load environment-specific variables
         */
        var envConfig = grunt.file.readJSON('conf.' + target + '.json');
    
        /**
         * This is the configuration object Grunt uses to give each plugin its
         * instructions.
         */
        grunt.initConfig({
            env: envConfig,       
    
            /*****************************************/
            /* Build files to a specific env or mode */
            /*****************************************/
            preprocess: {
                options: {
                    context: {
                        ENV_WS_URL: '<%= env.wsUrl %>'
                    }
                },
                constants: {
                    src: 'constants.tpl.js',
                    dest: 'constants.js'
                }
            },
    
            karma: {
                unit: {
                    configFile: '<%= src.karma %>',
                    autoWatch: false,
                    singleRun: true
                },
                watch: {
                    configFile: '<%= src.karma %>',
                    autoWatch: true,
                    singleRun: false
                }
            }
    
        });
    
    
        /****************/
        /* Plugins load */
        /****************/
        grunt.loadNpmTasks('grunt-preprocess');
    
        /*******************/
        /* Available tasks */
        /*******************/
        grunt.registerTask('run', 'Run task, launch web server for dev part', ['preprocess:constants']);
    
    };
    

    Now, the command :

    > grunt run --target=dev
    

    will create a new file with an url

    0 讨论(0)
  • 2020-12-10 05:46

    asumming you created a service that gets configuration object from server

    app.run(function($rootScope, yourService){   
        yourService.fetchConfig(function(config){
            $rootScope.baseUrl = config.baseUrl;
       })
    });
    

    markup

    <html ng-app="yourApp">
    <head>
       <base ng-href="{{baseUrl}}">
       ......
    

    note

    • If your service uses $http or $resource you should be fine
    • If instead you use jQuery ajax calls you should run $rootScope.$apply() after setting variables to the scope.
    0 讨论(0)
  • 2020-12-10 05:49

    I have tried to solve this problem and I really don't want to put my base path in some config file. We are working with many developers on our app and they each have different working environment. Finally I found out a solution which I am not really proud of, but it works like a charm. It requires only one thing: PHP.

    So instead of writing base href with your JS in head, try this:

    <?php
        $path = dirname($_SERVER['SCRIPT_NAME']);
        $uri = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].$path.'/';
        echo '<base href="' . $uri . '" />';
    ?>
    

    If you already have PHP on your server, then this is only matter of renaming your index.html to index.php (also dont forget about .htaccess if you have one).

    I know that this solution isn't good for everybody, it is not supposed to, it's just my solution of problem for those, who have PHP already on server. I hope this helps for at least some of you :)

    0 讨论(0)
  • 2020-12-10 05:54

    using base urls might not be the best thing because it might also screw up the functioning of the anchor tags and might lead to un wanted navigation. The approach that you have to read the configuration from an XML file is perfect and this is what i did:

    1.Before initializing your angular app read a variable from your config file:

    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp = new XMLHttpRequest();
    }
    else {// code for IE6, IE5
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.open("GET", "config.xml", false);
    xmlhttp.send();
    xmlDoc = xmlhttp.responseXML;
    

    let your config.xml have such a field

    <?xml version="1.0" encoding="utf-8" ?>
    <config>  
    <url>http://dev/ur/</url>
    </config>
    

    2.now inject a constant in your app for this i was guided by Eddiec and Cd

    var myApp= angular.module("App", ["ui.router"]).constant('BASE_URL',    
      xmlDoc.getElementsByTagName("url")[0].childNodes[0].nodeValue);
    

    3.you can use BASE_URL anywhere across your app you need to inject it this is how i used it to avoid hard coded paths in ui.router.js

    var routeResolver = function ($stateProvider, $urlRouterProvider,BASE_URL){
      $stateProvider
        .state('home', {
            url: "/Home",
            views: {
                "main-view": {
                    templateUrl: BASE_URL+"/views/Home.htm",
                    controller: "homeCtrl",
                    resolve: {
    
                    }
                }
            }
        })
    }
    myApp.config(routeResolver);
    

    hope it helps cheers!

    0 讨论(0)
提交回复
热议问题