Вопрос по config, base-url, angularjs, .htaccess, environment – Как установить базовый URL AngularjJS динамически в зависимости от выбранной переменной среды?

10

У меня есть среда разработки и производства, в которой мой URLотличаются:

производство:

www.exmaple.com/page

развитие:

dev.environment/project/page

Я знаю, что могу установить базовый URL в AngularJS с помощью

но это нене помогите мне здесь. Перед загрузкой приложения 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;
      });
    });

Есть ли способ динамически установить базовый URL, основанный на извлеченном файле конфигурации в AngularJS (может быть, с .htaccess)?

Попытка 1: Попробуй получить конфиг через.run и установите базовый URL через ng-href:

Отредактируйте следующую строку кода в моем 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();
});

и в моем index.html:


Похоже, это не работает: когда я изменяю атрибут href тега на ng-href, он корректно загружает контент, но изменяет мой URL-адрес наdev.environment/page вместоdev.environment/project/page

ОБНОВИТЬ: Конфигурационный файл:

{
  "mode": "development",
  "baseUrl": "/project/"
}
Я только добавил это < Daan
Можете ли вы показать нам свой config.json? Craig
на самом деле не уверен, что подразумевается или что вам нужно помочь с charlietfl
Получение и настройка с помощью тега скрипта - это не тот способ, которым я хочу это делать (я хочу использовать фреймворк). Парсинг location.href - вариант, но опять же, как именно вы это сделаете, используя фреймворк? Daan

Ваш Ответ

4   ответа
6

grunt

Когда я запускаю свое приложение angular, у меня есть несколько задач:

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

Затем хрюкать сделать замену строк с помощьюgrunt-preprocess модуль:

мойconstants.tpl.js файл анализируется:

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

и URL заполняется.

Есть бесконечные возможности (замена строк, копирование файлов и т. Д.).

Выполнение этого с grunt гарантирует, что файлы конфигурации dev не будут запущены в производство, например ..

Я могу поставить больше деталей, если выЯ заинтересован, но я только хотел показать вам другой подход.

редактировать пример 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']);

};

Теперь команда:

> grunt run --target=dev

создаст новый файл с URL

Ты знаешь ворчание? Если нет, то область действия этого ответа будет слишком большой, и я предлагаю вам прочитать grunt docs;) Я обновил свой ответ, чтобы дать вам лучший пример (не проверено, очень упрощенный код) Cétia
Очень интересно, можете ли вы дать мне небольшой пример того, какой дополнительный код мне понадобится, чтобы эта работа? Я предпочитаю не работать с базовым тегом, как объяснил @Rishul Matta Daan
Кажется, нет ответа, интегрированного с AngularJS, которыйпочему это самое чистое решение Daan
0

и я действительно неЯ не хочу указывать мой базовый путь в каком-либо конфигурационном файле. Мы работаем со многими разработчиками над нашим приложением, и у каждого из них разная рабочая среда. Наконец я нашел решение, которым я не очень горжусь, но оно работает как шарм. Требуется только одно: PHP.

Поэтому вместо написания base href с вашим JS попробуйте следующее:

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

Если у вас уже есть PHP на вашем сервере, то это только вопрос переименования вашегоindex.html вindex.php (также не забывайте о.htaccess если у тебя есть).

Я знаю, что это решение неэто хорошо для всех, это не должно, этоЭто просто мое решение проблемы для тех, у кого PHP уже есть на сервере. Я надеюсь, что это поможет, по крайней мере, некоторым из вас :)

1

поскольку оно также может испортить функционирование якорных тегов и может привести к нежелательной навигации. Подход, который вы должны прочитать конфигурацию из файла XML, идеален, и вот что я сделал:

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;

пусть ваш config.xml имеет такое поле

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

2. Теперь ввести константу в вашем приложении для этого я руководствовалсяEddiec а такжеCD

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

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

надеюсь, это помогает ура!

Я согласен, использование базового тега плохо и портит мои якоря. Но я предпочитаю (потому что я работаю в среде JS) файл JSON в вашем примере, и я неМне нравится тот факт, что мне нужно запустить файл перед инициализацией моего приложения Angular (но, возможно, это единственный способ). Daan
хм, что бы вы ни делали ... чтобы прочитать конфигурацию, вам нужно будет запустить файл перед запуском приложения, и более того, json - это улучшение по сравнению с xml, которое я написал для xml, вы также можете получить код для json :) Rishul Matta
3
как бы вы создали сервис, который получает объект конфигурации с сервера
app.run(function($rootScope, yourService){   
    yourService.fetchConfig(function(config){
        $rootScope.baseUrl = config.baseUrl;
   })
});
наценка


   
   ......
нотаЕсли ваш сервис использует $ http или $ resource, у вас все будет хорошоЕсли вместо этого вы используете jQuery ajax-вызовы, вы должны запустить $ rootScope. $ Apply () после установки переменных в область видимости.
Похоже, это не работает: когда я изменяю атрибут href для <база> тег к ng-href, он корректно загружает контент, но меняет мой URL наdev.environment/page вместо .dev.environment/project/page Daan
Я также пытался изменить <база> тег к, но это дает мне следующую ошибку:Error: A history state object with URL 'http://0.0.1.148/' cannot be created in a document with origin 'http://dev.environment'., Может быть, приятно сказать, что я также использую angular-ui-router Daan
Покажите мне переменные окружения, которые вы пытаетесь получить в базе href. Ilan Frumer
Этот ответ не будет работать + с помощью <base href = "" /> может использоваться для угловой структуры, но не будет соблюдаться обычными тегами привязки Daan
Я обновил свой вопрос Daan

Похожие вопросы