HTML5 PushState Regex Issue

I've been experimenting with Backbone for a project I'm working on, and I've been having problems with getting Backbone's 'pushState' functioning how I'd like to.

I've got a simple project consisting of 4 views, and a router. I'm routing via the id of the elements if it matters in this case. When I go to the hash for one of the views (http://example.com/backbonetest/#step1), it's displayed correctly, and the url is changed. This is what I'd expect to happen here, but the problem comes when I try and navigate to the same thing without the hash in it (http://example.com/backbonetest/step1). I get a 404 on the server (IIS) which is to be expected, as the page doesn't exist.

What I've been trying to do all day is write a regex expression for IIS which would catch and rewrite the url, removing the fragment at the end of the url so the page is served correctly. I'd rather simply rewrite the url than having a physical file with the same name, as the content of the page will be dynamically generated, and will require scripts to get the content anyway.

The issue I've come across may be related to how I need to have the folders/scripts/styles structured on the file system. I was hoping to be able to have the whole example contained within the /backbonetest/ folder. For scripts, 'backbonetest/scripts' and so on.

I made a list of URLs which I've been testing my regex expressions against, and the results I've been trying to achieve:

    Input:                  Output:

    2                       
    a2                      
    ab2                     
    ab22                    
    step2                   
    script.js               script.js
    scripts/                scripts/
    555/stuff               555/stuff
    scripts/script.js       scripts/script.js

Edit: I've since found that the url which is used does not include the preceding slash, which is why Qtax's solution doesn't work in IIS. The new input structure is shown above.

The '/555/stuff' url I would expect to 404 as normal. I only want to rewrite the url if there are no subdirectories defined other than the current one, and if the url doesn't reference an explicit file (one with an extension for example).

I've been scouring the net all day for a solution to this, as well as experimenting with regexr, but not managed to come up with the proper solution to my problem. After not finding a single thing anywhere, I'm thinking I must be looking at this the wrong way...

Can anyone help me out please?

Answers


After much head/desk banging, I've come up with the solution. It's irritatingly simple for all the fuss it's caused:

^[^\./]+$

Essentially:

Replace if the url doesn't contain a '/' or a '.' anywhere in it.

This should now be a solution for anyone using IIS with Backbone and HTML5 push state. Just pop it in the web.config in the root of your app, and change the rewrite action to ".", and it should just work.


This melted my brain all morning!

I've added to this - In my scenario, I have an API project which sits in an API virtual directory (to eliminate the need for CORS) - I obviously don't want to rewrite any of the PAI calls, so I re-wrote mine as follows - you can do similar for your API URLs if needed...

      <rule name="Handle PushState">
        <match url="^[^\./]+[^\./api]+(.*)$" />
        <conditions>
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        </conditions>
        <action type="Rewrite" url="." />
      </rule>

Need Your Help

bundler incorrectly trying to install "development" and "test" group gems in production

ruby-on-rails gem bundle bundler unicorn

I have a small web app, which uses a bunch of gems. Some of them are only used for test and development environments. Now, when I try to start unicorn on the production server using the following c...

How do I restrict my Android app to non-tablets?

android download google-play

I have seen this link which show how I can restrict download to only tablets, but I am looking the other way round.