Using a Relative Path for a Service Call in AngularJS

后端 未结 9 2038
别跟我提以往
别跟我提以往 2020-11-28 03:51

I have the following code, which was working fine until I deployed to a test server:

$scope.getUserList = function (userName) {
    $http({
        method: \         


        
相关标签:
9条回答
  • 2020-11-28 03:58

    I would just make all URL relative.

    url: "../GetUserList",
    

    instead

    url: "GetUserList",
    

    Hard coding for the, <base href="/application_root/" /> dose not sound good idea to me as you might need to change this environment to environment, and has dependency over virtual directory name.

    0 讨论(0)
  • 2020-11-28 04:02

    I would suggest defining a module that contains a global config that you can then pass around your application:

    // Module specific configuration
    angular.module('app.config')
      .value('app.config', {
        basePath: '/' // Set your base path here
      });
    

    Then you can access this from anywhere within your application thanks to AngularJS dependency injection:

    // Make sure your config is included in your module
    angular.module('app', ['app.config']);
    
    // Access your config e.g. in a controller
    angular.module('app')
      .controller('TestCtrl', ['$scope','app.config', function($scope, config){
    
        // Use config base path to assemble url
        $scope.url = config.basePath + 'GetUserList';
        ...
      }]);
    

    Whenever the base path changes (e.g. when you change to another server or host), you just need to change it in your global config and you're done.

    0 讨论(0)
  • 2020-11-28 04:06

    In the ng-init function pass a parameter that contains the value the virtual directory (int ASP.NET stored in Request.ApplicationPath).

    <div ng-controller="ControllerName" ng-init="init('@Request.ApplicationPath')">
    

    Inside the angular controller, use this value as prefix of URL in every http call. You can use this function to combine the paths

    function combinePath(path1, path2) {
        if (path1 == null) {
            return path2;
        }
        var last = path1.slice(-1);
        var first = path2.charAt(0);
    
        if (last == '/' && first == '/') {
            path1 = path1.substring(0, path1.length - 1);
        }
        return path1 + path2;
    }
    
    0 讨论(0)
  • 2020-11-28 04:12

    I'd suggest using an HTML base tag in the head, and coding all paths relative to this. In ASP.NET, for example, you can get a reference to the base of the application, which may or may not be the root path of the site, so using a base tag helps. Bonus: it works for every other asset too.

    You can have a base path like this:

    <base href="/application_root/" />
    

    ...and then links like "foo/bar.html" will actually be /application_root/foo/bar.html.

    Another approach I like to use is to put named links in the header. I will often have an API root in one location and a directive template root somewhere else. In the head, I'll then add some tags like this:

    <link id="linkApiRoot" href="/application_root/api/"/>
    <link id="linkTemplateRoot" href="/application_root/Content/Templates/"/>
    

    ... and then use $provide in the module to get the link href and expose it to services and directives like so:

    angular.module("app.services", [])
        .config(["$provide", function ($provide) {
            $provide.value("apiRoot", $("#linkApiRoot").attr("href"));
        }]);
    

    ... and then inject it to a service like this:

    angular.module("app.services").factory("myAdminSvc", ["apiRoot", function (apiRoot) {
        var apiAdminRoot = apiRoot + "admin/";
        ...
    

    Just my opinion though. Do the least complex thing for your application.

    0 讨论(0)
  • 2020-11-28 04:13

    I wasn't able to use <base> tag since my application was created in a popup dynamically from another origion. I was considering the others option in this thread to use something like a basePath variable and use it in every $http, ng-src, templateUrl etc

    But that was a bit overhead, built a interceptor that change every url before a xhr is made

    var app = angular.module("myApp", []);
    
    app.config(["$httpProvider", function($httpProvider) {
        $httpProvider.interceptors.push('middleware');
    }]);
    
    app.factory('middleware', function() {
        return {
            request: function(config) {
                // need more controlling when there is more than 1 domain involved
                config.url = "//example.com/api/" + config.url
                return config;
            }
        };
    });
    
    app.controller("Ctrl", ["$http", function($http) {
        $http.get("books"); // actually requestUrl = http://example.com/api/books
    }])
    

    And html aswell

    <div ng-include src="'view'">
        <!-- actually src = http://example.com/api/view -->
    </div>
    

    But i do recommend to use <base> tag instead unless you are using window.popup()

    0 讨论(0)
  • 2020-11-28 04:17

    I had a similar problem I solve it with the just one line of code in my MVC page

    <base href="~/" />
    
    0 讨论(0)
提交回复
热议问题