包含“点”的url查询参数的Angular ui-router

时间:2015-10-05 18:40:36

标签: angularjs angular-ui-router urlencode query-parameters

在我们的Angular应用程序中,我们必须处理包含“点”的id。例如:

<!DOCTYPE html>
<html lang="en-us">
    <head>
        <title>Bug</title>

        <link rel="stylesheet" type="text/css" href="jwm.css">

    </head>
    <body>

        <button onclick="sayHello()">Click me</button><br>
        <!-- <button>Click me</button><br> -->

        <script>
            // Encapsulate the client code in this single function.
            //
            function runClient(sock,beatsPerCycle,beatsPerMinute) {

                // Do necessary fallbacks to get the user media.
                navigator.getUserMedia = (navigator.getUserMedia ||
                          navigator.webkitGetUserMedia ||
                          navigator.mozGetUserMedia ||
                          navigator.msGetUserMedia);

                // Set up the context.
                var audioContext = new AudioContext();

                // Set up the script node that does all the work.
                var scriptNode = audioContext.createScriptProcessor(0, 2, 2);

                scriptNode.onaudioprocess = function(audioProcessingEvent) {
                    console.log("scriptNode.onaudioprocess");
                };

                if (navigator.getUserMedia) {
                    navigator.getUserMedia(
                        {
                            audio: true
                        },
                        function (stream) {
                            var source = audioContext.createMediaStreamSource(stream);
                            // Next line courtesy of
                            // https://support.mozilla.org/en-US/questions/984179
                            window.horrible_hack_for_mozilla = source;
                            source.connect(scriptNode);
                            scriptNode.connect(audioContext.destination);
                        },
                        function(err) {
                            console.log("The following getUserMedia error occured: " + err);
                            throw("");
                        }
                    );
                } else {
                    console.log("browser does not have getUserMedia.");
                }
            }

            function sayHello() {
                console.log("hello");
            }

            runClient()
        </script>

    </body>
</html>

我们在使用此类ID作为url参数时遇到问题。如果通过“Angular”进行导航,即点击调用book = { id: '123.456' } 的链接,则一切正常。但重新加载页面时,事情不起作用

“无法获取/bookDetails?bookId=123.456”

在控制器中:

$state.go('bookDetails', {bookId: book.id});
视图中的

$scope.viewBookDetails = function() {
    $state.go('bookDetails', {bookId: book.id});
}

在路由器中:

<a href="" ng-click="viewBookDetails(); $event.stopPropagation();">
浏览器中的

.state('bookDetails', {
    url: '/bookDetails?bookId'
}

如果在浏览器中将“点”替换为https://example.com/bookDetails?bookId=123.456 ,则该链接有效。

我们尝试在$ state.go()的参数中将“dot”替换为“%2E”

%2E

但不起作用,因为“%”会自动编码,浏览器中的“点”会被“%252E”替换

$scope.viewBookDetails = function() {
    $state.go('bookDetails', {bookId: book.id.split('.').join('%2E')});
}

3 个答案:

答案 0 :(得分:5)

我使用包含&#39;点&#39;的网址查询参数获得的刷新问题是一个服务器问题 它是由我在grunt服务器设置中处理html5mode(重定向到index.html,如果不是静态资源)的方式引起的

// The original grunt server settings
connect: {
  options: {
    port: 9000,
    // Change this to '0.0.0.0' to access the server from outside.
    hostname: 'localhost',
    livereload: 35729
  },
  livereload: {
    options: {
      open: true,
      middleware: function (connect) {
        return [
          require('connect-modrewrite')(['^[^\\.]*$ /index.html [L]']), //Matches everything that does not contain a '.' (period) and causes the problem
          connect.static('.tmp'),
          connect().use(
            '/bower_components',
            connect.static('./bower_components')
          ),
          connect().use(
            '/app/styles',
            connect.static('./app/styles')
          ),
          connect.static(appConfig.app)
        ];
      }
    }
  },

我改变了

require('connect-modrewrite')(['^[^\\.]*$ /index.html [L]']),

require('connect-modrewrite')([
  '!\\.html|\\.js|\\.css|\\.svg|\\.jp(e?)g|\\.png|\\.gif|\\.ttf$ /index.html'
]),

答案 1 :(得分:2)

如果您在服务器上使用http://symfony.com/doc/current/book/routing.html#adding-requirements(例如connect-history-api-fallback),则默认情况下不会重写带点的网址。

lite-server

if (parsedUrl.pathname.indexOf('.') !== -1) {
  logger(
    'Not rewriting',
    req.method,
    req.url,
    'because the path includes a dot (.) character.'
  );
  return next();
}

connect-history-api-fallback版本 1.2.0 connect-history-api-fallback code开始,您可以使用URLs with dots are allowed

来解决this problem

示例

如果带有点的网址为/api/test/:id(例如/api/test/123.34)且您的角网应用位于index.html页面,则可以向connect-history-api-添加重写规则像这样的后退

rewrites: [
  {
    from: /^\/api\/test\/[0-9]+\.[0-9]+$/,
    to: 'index.html'
    }
  }
]

答案 2 :(得分:1)

我完全修改了代码。我可以使用精细的点,所以请将plunker分叉以显示出错的位置。

http://plnkr.co/edit/Ct09Q9uoc282JuWdsO1s?p=preview

&#13;
&#13;
console.log("Scripts loading... ");

// Here's a skeleton app.  Fork this plunk, or create your own from scratch.
var app = angular.module('demonstrateissue', ['ui.router']);

app.controller('myController', function($scope, $state){
  $scope.book = {
  id: '123.456'
};
  
  $scope.viewBookDetails = function() {
    console.log('new id');
    $state.go('bookDetails', {bookId: 456.3456});
  }
});



// Empty config block.  Define your example states here.
app.config(function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider) {
  $stateProvider.state('bookDetails', {
    url: '/bookDetails:bookId',
    controller: function($scope, $stateParams) { 
      $scope.book = {
       id: $stateParams.bookId
      };
    },
    template: "<h3>book: {{book}}</h3>"
  });

  $urlRouterProvider.otherwise("/bookDetails/91.23");
});

// Adds state change hooks; logs to console.
app.run(function($rootScope, $state, $location) {
  
  $rootScope.$state = $state;
  $rootScope.$location = $location;
  
  function message(to, toP, from, fromP) { 
    return from.name  + angular.toJson(fromP) + " -> " + to.name + angular.toJson(toP);
  }
  
  $rootScope.$on("$stateChangeStart",   function(evt, to, toP, from, fromP)      { console.log("Start:   " + message(to, toP, from, fromP)); });
  $rootScope.$on("$stateChangeSuccess", function(evt, to, toP, from, fromP)      { console.log("Success: " + message(to, toP, from, fromP)); });
  $rootScope.$on("$stateChangeError",   function(evt, to, toP, from, fromP, err) { console.log("Error:   " + message(to, toP, from, fromP), err); });
});
&#13;
body { 
  margin-top: 6em;
}
.link { 
    text-decoration: underline;
    color: blue;
}

.link:hover {
    cursor: pointer;
}

.header { 
  position: fixed;
  right: 0;
  top: 0;
  height: 6em;
  width: 100%;
  border-bottom: 1px solid gray;
}
&#13;
<!DOCTYPE html>
<html>
  <head>
    <script src="https://code.angularjs.org/1.2.25/angular.js"></script>
    <script src="https://rawgit.com/angular-ui/ui-router/0.2.13/release/angular-ui-router.js"></script>
    <script src="main.js"></script>
    <link rel="stylesheet" href="styles.css" />
    <title>Plunk demonstrating ui-router issue</title>
  </head>

  <body ng-app="demonstrateissue">

      <div ui-view>ui-view not populated</div>  
    
      <div class="header">
        Current URL: <b>{{$location.url() }}</b> <br>
        Current State: <b>{{$state.current.name }}</b> <br>
        Current Params: <b>{{$state.params | json }}</b><br>
      </div>
    <br/>
    <br/>
    <div ng-controller="myController">
      {{book}}
      <br/>
      <a ui-sref="bookDetails({bookId: 6789.1011})">Change params to book with dot</a><br/>
      <button ng-click="viewBookDetails()">View Book Details</button>
      </div>
  </body>
</html>
&#13;
&#13;
&#13;