madvora
madvora

Reputation: 1747

Get proper root in javascript file

I'm having a problem with resolving the root of a URL between my local machine and after deploying an application on IIS to our dev server.

The url when running locally is something like this. http://localhost:57173/

the url when running on the dev server is something like this. http://ServerName/AppName

I have JQuery Ajax calls to a web api and it won't find the location on the dev server if the trailing slash is left off.

Here's the call

$.ajax({
    type: "GET",
        url: "api/MyApi/Get",
        data: { period: selectedPeriod },
        cache: false,
        success: function (data) {

        }
    });

If I look in FireBug at the api call on the dev server, with the trailing slash left off, it will show

http://ServerName/api/MyApi/Get

If I do have the trailing slash, it will resolve correctly to this. (Notice the AppName now included.)

http://ServerName/AppName/api/MyApi/Get

What am I missing here? It looks like it's not finding the proper root of the application when I move it to this server. The trailing slash makes no difference locally. It will find the api either way. Any ideas how to resolve this?

Upvotes: 2

Views: 2836

Answers (3)

Javier Gonzalez
Javier Gonzalez

Reputation: 1015

I also had this issue, the way to solved it was declare a javascript variable that contains the part of the url that differs in both environments (dev and local) and prepend that to every ajax request:

I put that variable in the layout file (Views/Shared/_Layout.cshtml), so that it could be automatically filled by ASP.NET and then used globally (make sure to create the script before the @RenderSection call):

  ...
  <script>
    var baseUrl = @Html.Raw(Json.Encode(Url.Content("~")));
  </sctipt>
  @RenderSection("scripts", required: false) 
</body>
...

Then prepend that variable in the url of the ajax call (for example View/Home/Index.cshtml):

    @section scripts {
      $.ajax({
        type: "GET",
        url: baseUrl + "api/MyApi/Get",
        data: { period: selectedPeriod },
        cache: false,
        success: function (data) {} 
     });
   }

Upvotes: 2

Erik Philips
Erik Philips

Reputation: 54628

Javascript typically doesn't run unless the user causes an event to occur. I prefer to use the following because it allows MVC to get the exact route properly everytime no matter where you deploy.

Html

<button data-url="@Url.Action("MyApi", "Get")"></button>

Javascript

$(document).ready(function()
{
  $('button').on('click', function()
  {
    var url = $(this).data('url');
    $.ajax({
      type: "GET",
      url: url,
      data: { period: selectedPeriod },
      cache: false,
      success: function (data) {
    });
  });
});

Hard coding a url in javascript I consider bad-practice.

Upvotes: 1

Grax32
Grax32

Reputation: 4059

A url without a leading slash is considered a relative url. Your url "api/MyApi/Get" will be resolved by the browser relative to the url of the page containing the script.

http://ServerName/AppName appears to the browser as if it is a page request, with AppName being the name of the page and the AppName is not considered when resolving the url.

http://ServerName/AppName/ (trailing slash) appears to the browser as a directory request and becomes the base of your relative url.

The best fix for this is probably to redirect requests for http://ServerName/AppName to http://ServerName/AppName/

To do the redirect from within your application, insert the following into your /Home/Index controller action (before any other code)

if (!Request.Url.AbsolutePath.EndsWith("/"))
{
    return Redirect("~/");
}

This will redirect any request for http://ServerName/AppName to http://ServerName/AppName/ As a side effect, it would also redirect any requests for http://ServerName/AppName/Index to http://ServerName/AppName/ but I don't think that would cause you any problems.

Upvotes: 2

Related Questions