Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relative Path Problems in Javascript Ajax call

Okay, I have a JavaScript file with the following functions:

function AskReason() {
    var answer = prompt("Please enter a reason for this action:", "");
    if (answer != null)
        DoReason(answer);
}

function createXMLHttpRequest() {
    try {
        return new XMLHttpRequest();
    }
    catch (e)
    { alert('XMLHttpRequest not working'); }
    try {
        return new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    { alert('Msxml2.XMLHTT not working'); }
    try {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e)
    { alert('Microsoft.XMLHTTP not working'); }
    alert("XMLHttpRequest not supported");
    return null;
}

function DoReason(reason) {
    var xmlHttpReq = createXMLHttpRequest();
    var url = "/Shared/AskReason.ashx?REASON=" + reason;
    xmlHttpReq.open("GET", url, true);
    xmlHttpReq.send(null);
}

This line:

    var url = "/Shared/AskReason.ashx?REASON=" + reason;

Is what is causing the problem.

In VS 2010 debugging the app - this call works to my ashx handler.

When I move the project to a virtual directory - example http://localhost/myapp

this code will break and I have to change the javascript to this:

var url = "http://localhost/myapp/Shared/AskReason.ashx?REASON=" + reason;

Any ideas on how I can fix this to work in both environments or just accept the manual change when I deploy apps to servers?

Thanks, Mike

like image 447
MDV2000 Avatar asked Feb 23 '11 14:02

MDV2000


People also ask

What is a relative path Example?

A relative path is a way to specify the location of a directory relative to another directory. For example, suppose your documents are in C:\Sample\Documents and your index is in C:\Sample\Index. The absolute path for the documents would be C:\Sample\Documents.

What is a relative path Javascript?

A link that has an absolute path will tell the computer which server to go to and then all the folders that you have to drill down through to get to the target. A link that has a relative path will be written to tell the computer how to get from the folder with the currently viewed topic to the target.

How do you specify a relative path?

A relative path refers to a location that is relative to a current directory. Relative paths make use of two special symbols, a dot (.) and a double-dot (..), which translate into the current directory and the parent directory. Double dots are used for moving up in the hierarchy.


5 Answers

Pointy's way works, but you have to know in advance where you're going to deploy it.

Alternately, simply don't start the relative path with a /:

var url = "Shared/AskReason.ashx?REASON=" + reason;

That will be resolved relative to the current document's location. So if the current document is:

http://localhost/myapp/index.aspx

...then that will resolve to

http://localhost/myapp/Shared/AskReason.ashx?REASON=foo
like image 51
T.J. Crowder Avatar answered Oct 01 '22 18:10

T.J. Crowder


Paths that start with a "/" (and no protocol & host) are relative to the root of the host. If you deploy such that your application is at "http://whatever/myapp", then your root-relative paths have to start with "/myapp".

When you're working in a server-side environment that involves some sort of page template mechanism, a common trick is to have that part of the path be some kind of configuration variable so that you can write pages with paths like:

<a href='${root}/something/something'>click me</a>

Then that "root" variable is expanded based on configuration to "/myapp" or whatever.

like image 29
Pointy Avatar answered Oct 01 '22 20:10

Pointy


I had a similar problem where an absolute URL was needed but the reference broke when going from localhost to the production server. I resolved it by checking if a "localhost" string exists in:

var environ = window.location.host;

Then you can simply do:

if (environ === "localhost") {
    var baseurl = window.location.protocol + "//" + window.location.host + "/" + "shared/";
} else {
    var baseurl = window.location.protocol + "//" + window.location.host + "/";
}

Then you can add baseurl in front of whatever url you need to reference.

like image 29
chromaloop Avatar answered Oct 01 '22 19:10

chromaloop


The url

var url = "/Shared/AskReason.ashx?REASON=" + reason; 

Is looking for the file in the root directory [since it is an absolute path], effectively

http://localhost/Shared/AskReason.ashx

You should include the name of the virtual directory OR determine the appropriate structure:

Starting without the / will give you a relative path ... if you need to navigate directories use ../Shared/ style of notation, or finally use your servers Directory command to determine your current path.

like image 38
iivel Avatar answered Oct 01 '22 19:10

iivel


I have the same issue with ASP.NET MVC with my AJAX call on a separate .js file. This is how it looks:

 return $.ajax({
            type: "POST",
            url: '/Dashboard/Execute',
            contentType: "application/json; charset=utf-8",
            data: filter,
            dataType: "json",
        });

This works fine on my local, of course. But when deployed on a subdirectory in IIS, e.g.

wwwroot/appsite/subdomainfolder/

This will trigger 404 Not Found as it didn't attach the subdomainfolder on the URL.

If I remove the

"/"

at the beginning of the URL, it will generate it like this one:

http://localhost/subdomainfolder/Dashboard/Dashboard/ExecuteReader

Which again will trigger the 404 Not Found issue.

So here are the two options for my workaround:

Remove the backslash and remove the name of the controller (Dashboard on this case):

return $.ajax({
            type: "POST",
            url: '/Execute',
            contentType: "application/json; charset=utf-8",
            data: filter,
            dataType: "json",
        });

Or, stay as it is, just add double period at the beginning of the URL:

return $.ajax({
            type: "POST",
            url: '../Dashboard/Execute',
            contentType: "application/json; charset=utf-8",
            data: filter,
            dataType: "json",
        });
like image 27
Willy David Jr Avatar answered Oct 01 '22 19:10

Willy David Jr