如何根据获取的环境变量动态设置AngularjJS基URL ?

时间:2022-09-12 23:24:39

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

我有一个不同于URL的开发和生产环境:

production:

生产:

www.exmaple.com/page

www.exmaple.com/page

development:

发展:

dev.environment/project/page

dev.environment /项目/页面

I know that I can set the base URL in AngularJS with the

我知道我可以用

<base href='/project/' />

<基地href = ' 项目>

but that doesn't help me out here. Before I load my AngularJS application I fetch a config file (in app.js, with the .run statement, which reads a variable that has the environment:

但这对我没有帮助。在加载AngularJS应用程序之前,我将获取一个配置文件(在app.js中,使用.run语句,该语句读取具有环境的变量:

]).run([
  '$rootScope',
  '$http',
  function (
    $rootScope,
    $http
  ) {
    var configDeferred = $q.defer();

    // fetch config and set the API    
    $http.get('config.json').then(function(response) {
      $rootScope.config = response.data;
      configDeferred.resolve();
    });

    // Wait for the config to be loaded, then go to state
    $rootScope.$on('$stateChangeStart', function (event, next, current) {
      event.preventDefault();
      $q.all([configDeferred.promise]).then(function() {
        $state.transitionTo(next.name);
        return;
      });
    });

Is there a way to dynamically set the base URL, based on a fetched config file in AngularJS (maybe with a .htaccess)?

有没有一种方法可以根据在AngularJS中获取的配置文件(可能是.htaccess)动态设置基本URL ?

Attempt 1: Try to get the config via .run and set the base url via ng-href:

尝试1:尝试通过.run获取配置,通过ng-href设置基本url:

Edit the following line of code in my app.js:

在我的app.js中编辑以下代码行:

// fetch config and set the API    
$http.get('config.json').then(function(response) {
  $rootScope.config = response.data;
  $rootScope.baseUrl = response.data.baseUrl; // '/project/'
  configDeferred.resolve();
});

and in my index.html:

在我的index . html:

<base ng-href="{{baseUrl}}" />

It looks like this is not working: when I change the href attribute of tag to ng-href, it loads the content correctly, but changes my URL to dev.environment/page instead of dev.environment/project/page

它看起来是不工作的:当我将标记的href属性更改为ng-href时,它会正确地加载内容,但是将我的URL更改为dev.environment/页面,而不是dev.environment/project/page。

UPDATE: The config file:

更新:配置文件:

{
  "mode": "development",
  "baseUrl": "/project/"
}

4 个解决方案

#1


6  

I personnaly do this kind of stuff with grunt.

我自己也会咕哝着做这种事。

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

当我运行我的angular应用程序时,我有多个任务:

> 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 :

然后在grunt-preprocess模块的帮助下,对字符串进行替换:

my constants.tpl.js file gets parsed :

我的constants.tpl。js文件被解析:

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

and the url is populated.

url被填充。

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..

使用grunt确保开发配置文件不会进入生产环境。

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

如果你感兴趣的话,我可以提供更多的细节,但我只想给你展示一种不同的方法。

edit gruntFile example :

编辑gruntFile例子:

'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

是否将创建一个具有url的新文件

#2


3  

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
  • 如果您的服务使用$http或$resource,应该没问题
  • If instead you use jQuery ajax calls you should run $rootScope.$apply() after setting variables to the scope.
  • 如果您使用jQuery ajax调用,您应该在将变量设置到范围之后运行$rootScope.$apply()。

#3


1  

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:

使用基本url可能不是最好的方法,因为它可能会破坏锚标记的功能,并可能导致不需要的导航。您必须从XML文件中读取配置的方法是完美的,这就是我所做的:

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

1。在初始化你的角化应用之前,从你的配置文件中读取一个变量:

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有这样一个字段

<?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

2。现在在你的应用中注入一个常数我是由Eddiec和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

3所示。你可以在应用程序的任何地方使用BASE_URL你需要注入它这就是我如何使用它来避免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!

希望它能帮助干杯!

#4


0  

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.

我已经尝试解决这个问题,我真的不想把我的基本路径放到某个配置文件中。我们正在和许多开发人员一起开发我们的应用,他们都有不同的工作环境。最后我找到了一个我并不引以为豪的解决方案,但它很有魅力。它只需要一件事:PHP。

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

所以,不要用你的JS来写base href,试试这个:

<?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).

如果您的服务器上已经有PHP,那么这只是重命名索引的问题。html索引。php(如果有.htaccess,也不要忘记)。

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 :)

我知道这个解决方案并不适合所有人,它不应该适合所有人,它只是我对那些已经在服务器上有PHP的人的问题的解决方案。我希望这至少对你们有些人有帮助。

#1


6  

I personnaly do this kind of stuff with grunt.

我自己也会咕哝着做这种事。

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

当我运行我的angular应用程序时,我有多个任务:

> 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 :

然后在grunt-preprocess模块的帮助下,对字符串进行替换:

my constants.tpl.js file gets parsed :

我的constants.tpl。js文件被解析:

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

and the url is populated.

url被填充。

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..

使用grunt确保开发配置文件不会进入生产环境。

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

如果你感兴趣的话,我可以提供更多的细节,但我只想给你展示一种不同的方法。

edit gruntFile example :

编辑gruntFile例子:

'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

是否将创建一个具有url的新文件

#2


3  

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
  • 如果您的服务使用$http或$resource,应该没问题
  • If instead you use jQuery ajax calls you should run $rootScope.$apply() after setting variables to the scope.
  • 如果您使用jQuery ajax调用,您应该在将变量设置到范围之后运行$rootScope.$apply()。

#3


1  

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:

使用基本url可能不是最好的方法,因为它可能会破坏锚标记的功能,并可能导致不需要的导航。您必须从XML文件中读取配置的方法是完美的,这就是我所做的:

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

1。在初始化你的角化应用之前,从你的配置文件中读取一个变量:

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有这样一个字段

<?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

2。现在在你的应用中注入一个常数我是由Eddiec和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

3所示。你可以在应用程序的任何地方使用BASE_URL你需要注入它这就是我如何使用它来避免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!

希望它能帮助干杯!

#4


0  

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.

我已经尝试解决这个问题,我真的不想把我的基本路径放到某个配置文件中。我们正在和许多开发人员一起开发我们的应用,他们都有不同的工作环境。最后我找到了一个我并不引以为豪的解决方案,但它很有魅力。它只需要一件事:PHP。

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

所以,不要用你的JS来写base href,试试这个:

<?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).

如果您的服务器上已经有PHP,那么这只是重命名索引的问题。html索引。php(如果有.htaccess,也不要忘记)。

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 :)

我知道这个解决方案并不适合所有人,它不应该适合所有人,它只是我对那些已经在服务器上有PHP的人的问题的解决方案。我希望这至少对你们有些人有帮助。