Как получить относительный путь в Javascript? - PullRequest
13 голосов
/ 10 июня 2011

В моем веб-проекте ASP.net я написал следующий код Javascript в файле .js:

function getDeviceTypes() {
    var deviceTypes;
    $.ajax({
        async: false,
        type: "POST",
        url: "Controls/ModelSelectorWebMethods.aspx/getDeviceTypes",
        data: '{ }',
        contentType: "application/json;",
        dataType: "json",
        success: function(response) {
            deviceTypes = response.d;
        },
        error: function(xhr, status) {
            debugger;
            alert('Error getting device types.');
        }
    });    // end - $.ajax
    return deviceTypes;
}

Он работал прекрасно, пока я не попытался загрузить этот файл .js на страницу.в подкаталоге.

Предположим, что имя моего проекта widget.

Когда я использую этот код в главном виртуальном каталоге, Javascript интерпретирует Controls/ModelSelectorWebMethods.aspx/getDeviceTypes как значение https://mysite.com/widget/Controls/ModelSelectorWebMethods.aspx/getDeviceTypesи все хорошо.Однако на странице в подкаталоге Javascript интерпретирует его как значение https://mysite.com/widget/subdirectory/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes, и оно не работает.

Как мне написать свой код Javascript, чтобы веб-метод AJAX можно было вызывать со страниц в любомкаталог в моем приложении?

Ответы [ 6 ]

17 голосов
/ 10 июня 2011

У вас есть два варианта:

  1. Создайте объект конфигурации / предпочтений в JavaScript, который содержит все параметры, относящиеся к вашей среде:

     var config = {
         base: <% /* however the hell you output stuff in ASPX */ %>,
         someOtherPref: 4
     };
    

    , а затем префикс AJAX url с config.base (и измените значение на config.base, если вы находитесь на сервере разработки / тестирования / развертывания.)

  2. Используйте HTML-тег <base />, чтобы задать префикс URL для всех относительных URL. Это влияет на все относительные URL: изображения, ссылки и т. Д.

Лично я бы выбрал вариант 1. Скорее всего, этот объект конфигурации пригодится в другом месте.

Очевидно, что объект конфигурации должен быть включен в ту часть вашего сайта, где оценивается серверный код; файл .js не обрежет его без настройки вашего сервера. Я всегда включаю объект конфигурации в HTML <head>; это небольшой объект конфигурации, содержимое которого может меняться на каждой странице, поэтому совершенно разумно вставить его туда.

11 голосов
/ 10 июня 2011

Пока вы не заботитесь о asp.net виртуальных каталогах (что фактически делает невозможным определение из скрипта, вам придется что-то передавать с сервера), вы можете посмотреть на URL и разобрать его:

function baseUrl() {
   var href = window.location.href.split('/');
   return href[0]+'//'+href[2]+'/';
}

, то:

...
   url: baseUrl()+"Controls/ModelSelectorWebMethods.aspx/getDeviceTypes",
...

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

1) На вашей главной странице поместите код, чтобы внедрить скрипт куда-нибудь, желательно, прежде чем что-либо еще (я добавляю его непосредственно в HEAD, добавляя элементы управления вместо использования ScriptManager), чтобы убедиться, что он выполняется перед любым другим скриптом. c #:

string basePath = Request.ApplicationPath;
// Annoyingly, Request.ApplicationPath is inconsistent about trailing slash
// (if not root path, then there is no trailing slash) so add one to ensure 
// consistency if needed
string myLocation = "basePath='" + basePath + basePath=="/"?"":"/" + "';";
// now emit myLocation as script however you want, ideally in head

2) Измените baseUrl, чтобы включить это:

function baseUrl() {
   var href = window.location.href.split('/');
   return href[0]+'//'+href[2]+basePath;
}
4 голосов
/ 10 июня 2011

Создайте корневую переменную приложения ...

var root = location.protocol + "//" + location.host;

И используйте абсолютный URI (вместо относительного) при выполнении запросов AJAX ...

url: root + "/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes"
1 голос
/ 27 мая 2013

Я думаю, что эта функция будет работать ... она должна получить относительный путь как "../../../" поэтому, если вы вызовете эту функцию на каждой странице, она вернет формат относительного пути.

function getPath() {
    var path = "";
    nodes = window.location. pathname. split('/');
    for (var index = 0; index < nodes.length - 3; index++) {
        path += "../";
    }
    return path;
}
0 голосов
/ 21 августа 2014

Вы можете импортировать пространство имен в начале: System.Web.Hosting.HostingEnvironment

  <%@ Master Language="VB" AutoEventWireup="false" CodeFile="Site.master.vb" Inherits="Site" %>
   <%@ Import namespace="System.Web.Hosting.HostingEnvironment" %>

и в js:

  <script type="text/javascript">
        var virtualpathh = "<%=ApplicationVirtualPath  %>";
   </script>
0 голосов
/ 10 июня 2011

Не могли бы вы использовать window.location.pathname?

var pathname = window.location.pathname;
$.ajax({
    //...
    url: pathname + 'Controls/...', // might need a leading '/'
    //...
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...