1

In one webapp that I'm working with, I have deal with URLs like the one below:

http://localhost:8080/section/value.with.periods

This value.with.periods is a URL param, like the ones that you declare on angular's routeProvider:

angular.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
        .when('/section/:param', {
            templateUrl: 'url-to-template',
            controller: 'ExampleCtrl',
            resolve: {
                ...
            }
        });
}]);

The problem is that the server used, running under Grunt tasks, cannot handle URLs with periods in it:

Cannot GET /section/value.with.periods

I'm running Grunt with grunt-contrib-proxy and connect-modrewrite, and the livereload task, which configures the connect-modrewrite, is the one below:

        livereload: {
            options: {
                open: 'http://localhost:<%= connect.options.port %>',
                base: [
                    '.tmp',
                    '<%= config.app %>'
                ],
                middleware: function(connect, options) {
                    if (!Array.isArray(options.base)) {
                        options.base = [options.base];
                    }

                    // Setup the proxy
                    var middlewares = [proxySnippet];

                    var modRewrite = require('connect-modrewrite');
                    middlewares.push(modRewrite(['^[^\\.]*$ /index.html [L]']));
                    // middlewares.push(modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png|\\.jpg\\.gif|\\swf$ /index.html [L]']));


                    // Serve static files.
                    options.base.forEach(function(base) {
                        middlewares.push(connect.static(base));
                    });

                    // Make directory browse-able.
                    var directory = options.directory || options.base[options.base.length - 1];
                    middlewares.push(connect.directory(directory));

                    return middlewares;
                }
            }
        }

I need to be capable to deal with URLs with periods on the params used on Angular. Any help will be appreciated.

Thanks.

Mateus Leon
  • 1,381
  • 1
  • 14
  • 21

1 Answers1

2

Your rewrite regex excludes all paths with a period in it:

^[^\\.]*$

That means as much as: match urls with all characters, except when they have a backslash or a period. So /section/value.with.periods would be ignored.

You should change your regex to something more forgiving:

middlewares.push(modRewrite(['^(.*)$ /index.html [L]']));

And you should be good to go.

Edit solution:

In the comments we came to the answer: above regex will rewrite all urls to index.html, causing other files not to be served. There was a commented out line that only rewrites urls with unknown file extensions:

middlewares.push(modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png|\\.jpg|\\.gif|\\.swf$ /index.html [L]']));

That gives the desired result. See comments for more info.

Mike Causer
  • 8,196
  • 2
  • 43
  • 63
RoryKoehein
  • 3,113
  • 1
  • 14
  • 13
  • I've replaced the regex with your suggestion and the app wasn't capable to find any of its dependencies. All of them are now pointing to `index.html` as their source, throwing several errors on the console. I was thinking if this original regex should be adapted or if it serves only for files path declared on HTML tags. – Mateus Leon Jan 21 '15 at 00:26
  • 1
    There doesn't seem to be an option to check if a file exists as in apache's mod_rewrite. Did you try the commented out version? `middlewares.push(modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png|\\.jpg\\.gif|\\swf$ /index.html [L]']));` – RoryKoehein Jan 21 '15 at 11:56
  • Regex isn't my best ability. Yes, the uncomment worked. I didn't noticed the possibility of the uncommented regex, someone on the team has replaced for the other one and lead to this problem. Can I edit your answer, explaining, and mark as correct? – Mateus Leon Jan 21 '15 at 15:51