Относительные проблемы пути в Javascript Ajax call

Хорошо, у меня есть файл JavaScript со следующими функциями:

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);
}

Эта строка:

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

Является тем, что вызывает проблему.

В VS 2010 отладка приложения - этот вызов работает с моим обработчиком ashx.

Когда я перемещаю проект в виртуальный каталог - пример http://localhost/myapp

этот код сломается, и я должен изменить javascript на это:

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

Любые идеи о том, как я могу исправить это для работы в обеих средах или просто принять изменения вручную при развертывании приложений на серверах?

Спасибо, Mike

Ответ 1

Поощренный путь работает, но вы должны заранее знать, куда его развернуть.

В качестве альтернативы просто не начинайте относительный путь с помощью /:

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

Это будет разрешено относительно текущего местоположения документа. Итак, если текущий документ:

http://localhost/myapp/index.aspx

... то это разрешит

http://localhost/myapp/Shared/AskReason.ashx?REASON=foo

Ответ 2

Пути, начинающиеся с "/" (и без протокола и хоста), относятся к root хоста. Если вы развертываете, чтобы ваше приложение было "http://any/myapp", то ваши корневые пути должны начинаться с "/myapp".

Когда вы работаете в серверной среде, которая связана с каким-то механизмом шаблона страницы, общий трюк заключается в том, чтобы эта часть пути была какой-то конфигурационной переменной, чтобы вы могли писать страницы с такими путями, как:

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

Затем эта переменная "root" расширяется на основе конфигурации "/myapp" или что-то еще.

Ответ 3

У меня была аналогичная проблема, когда нужен абсолютный URL-адрес, но ссылка переходила при переходе с локального хоста на рабочий сервер. Я решил это, проверив, существует ли строка "localhost":

var environ = window.location.host;

Тогда вы можете просто сделать:

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

Затем вы можете добавить baseurl перед тем, что вам нужно для ссылки.

Ответ 4

URL

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

Ищет файл в корневом каталоге [поскольку это абсолютный путь], эффективно

http://localhost/Shared/AskReason.ashx

Вы должны указать имя виртуального каталога или определить соответствующую структуру:

Запуск без/даст вам относительный путь... если вам нужно перемещаться по каталогам, используйте стиль записи. /Shared/, или, наконец, используйте команду Directory, чтобы определить ваш текущий путь.

Ответ 5

У меня та же проблема с ASP.NET MVC с моим вызовом AJAX в отдельном файле .js. Вот как это выглядит:

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

Это хорошо работает на моем местном, конечно. Но при развертывании в подкаталоге в IIS, например,

wwwroot/appsite/subdomainfolder/

Это вызовет 404 Not Found, так как он не прикрепил поддомен к URL-адресу.

Если я удалю

"/"

в начале URL он будет сгенерирован следующим образом:

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

Что снова вызовет проблему 404 Not Found.

Итак, вот два варианта моего решения:

Удалите обратную косую черту и удалите имя контроллера (Dashboard в этом случае):

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

Или оставайтесь без изменений, просто добавьте двойной период в начале URL:

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