Relative URL in JQuery Post Call

2019-03-08 20:24发布

I have the following situation.

I developed my first MVC Asp.Net application. it runs on my server at the following adress

http://localhost:59441/

I wrote some JQuery Post Methods that looked like this

  $.ajax({
        type: "POST",
        url: "/CeduleGlobale/UpdateCheckBox", ...

CeduleGlobale is my ControllerName and UpdateCheckBox is my methodName

When I put the Application on the testServer, it was put in a VirtualDirectory

hence the application is now

http://testServer/JprApplication/

no more port to specify and also an application Name

When I started to test, I quickly noticed my JQuery Post calls didn't work anymore...

I modified them so now the URL is

/JprMvc/CeduleGlobale/UpdateCheckBox

the problem is 2 fold.

  1. this makes it hard to test on my development machine because IIS Express doesn't allow me to specify a virtual Directory.
  2. I don't like hardCoding the Virtual Directory Name in the JQuery because I dont know what name the Application will have in the production environment and therefore i will have to modify my script before i can install the application in production.

I am sure I am missing some basic thing to simplify this.

Thanks

7条回答
beautiful°
2楼-- · 2019-03-08 20:43

I had this kind issue on MVC 5 using JQuery, so I went to this solution that gets rid of the problem when you are in Localhost, and in any Navigator even when you're deploying app in a subfolder.

var pathname = window.location.pathname;
var VirtualDirectory;
if (pathname.indexOf("localhost") >= 0 && pathname.indexOf(":") >= 0) {
    VirtualDirectory = "";
}
else {
    if ((pathname.lastIndexOf('/')) === pathname.length + 1) {
        VirtualDirectory = pathname.substring(pathname.indexOf('/'), pathname.lastIndexOf('/'));
    } else {
        VirtualDirectory = pathname;
    }
}

And then in any ajax call :

$.post(VirtualDirectory + "/Controller/Action", { data: data}, "html")
             .done(function (result) {
                 //some code             
});
查看更多
Explosion°爆炸
3楼-- · 2019-03-08 20:50

@Tommy's answer was a great pointer, however for .NET Core I had to do things a little differently, as the Request object has different properties.

Things were made more tricky by deploying to a virtual directory but using IIS Express for development; hence the if statement when setting the base url.

Shared/_Layout.cshtml

<!-- Set the site root for javascript in _Layout.cshtml.-->
@if (!String.IsNullOrWhiteSpace(@Context.Request.PathBase.Value))
{
    /* LIVE - includes virtual directory */
    <script>
        window.siteRoot = "@Context.Request.Scheme" + "://" + "@Context.Request.Host.Value" + "@Context.Request.PathBase.Value" + "/";
    </script>
}
else
{
   /* DEBUG - no virutal directory, e.g. IIS Express */
    <script>
        window.siteRoot = "@Context.Request.Scheme" + "://" + "@Context.Request.Host.Value" + "/";
    </script>
}

Then from any JavaScript file

/* from any javascript file */
var url = window.siteRoot + 'MySearch/GetMySearchResults';

$.ajax({
    url: url,
    type: 'GET',
    cache: false,
    data: searchObj,
    success: function (result) {
        alert('yatta!');
    },
    fail: function (e, k, n) {
        alert('hmph!');
    },
    done: function() {
        // hide spinner
    }
});

Obviously you might wish to create your own namespace or something to save polluting window. I've tried to keep the example below as simple as possible.

查看更多
叛逆
4楼-- · 2019-03-08 20:53

As far as I know there is no other way around this. Unless you are willing to user relative URL's i.e:

$.ajax({
        type: "POST",
        url: "./CeduleGlobale/UpdateCheckBox", ...

But that can get messy for various reasons when you refactor code. Alternatively prepend the URL which is globally defined and therefore you then only need to change it in once place before going to production.

i.e.

//Globally defined serverRoot
serverRoot = "http://someaddress/somevirtualdirectory";

$.ajax({
        type: "POST",
        url: serverRoot + "/CeduleGlobale/UpdateCheckBox", ...

That way if you don't need it you can just set serverRoot = ''; and all will be back to how it is now.

查看更多
孤傲高冷的网名
5楼-- · 2019-03-08 20:54

I know this is an old post. But, I had the same issue and ended up here. And managed to fix that issue with UrlHelper.Action method. It should be used something like this. (Note that this specific solution will works within the view.)

url: "@Url.Action("UpdateCheckBox", "CeduleGlobale")",

Hope this helps. :)

查看更多
Summer. ? 凉城
6楼-- · 2019-03-08 20:57

http://localhost:59441/ and
http://testServer/JprApplication/ will both work with your

$.ajax({ type: "POST", url: "/CeduleGlobale/UpdateCheckBox", ...

if your hosting in iis you just need to create a virtual host in your
C:\Windows\System32\drivers\etc\hosts

file. Add this line at the bottom of your hosts file

127.0.0.1 CeduleGlobale

create a new site like so create a new site like this select sites, right click and create a new site

fill in your details and set the same hostname as you created above 'CeduleGlobale'

fill in your details and set the same hostname as you created above 'CeduleGlobale'

then deploy your mvc appliation to this site

查看更多
Lonely孤独者°
7楼-- · 2019-03-08 21:02

Pass @Url.Action("action","controller") to the javascript from the view. This will allow it to be update dynamically at run time.

<script>
   myJavascriptfunction(@Url.Action("action","controller"),param1,param2);
</script>

There may be a function to get the root path also which you could use to initialize the root variables in the previous answers.

查看更多
登录 后发表回答