如何在Javascript中获取相对路径?

Dan*_*don 13 javascript asp.net ajax jquery

在我的ASP.net Web项目中,我在.js文件中编写了以下Javascript代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

在我尝试将此.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 Web方法?

Mat*_*att 17

你有两个选择:

  1. 在JavaScript中构建配置/首选项对象,其中包含所有特定于环境的设置:

     var config = {
         base: <% /* however the hell you output stuff in ASPX */ %>,
         someOtherPref: 4
     };
    
    Run Code Online (Sandbox Code Playgroud)

    然后在AJAX url前加上config.base(并更改config.base您是否在dev/testing/deployment服务器上的值.)

  2. 使用<base />HTML标记为所有相对URL设置URL前缀.这会影响所有相对URL:图像,链接等.

就个人而言,我会选择选项1.您很可能会发现配置对象在其他地方派上用场.

显然,配置对象必须包含在您的站点中评估服务器端代码的部分; 一个.js没有自己的服务器配置文件将不会削减它.我总是在HTML中包含配置对象<head>; 它是一个小的配置对象,其内容可以在每个页面上进行更改,因此完全可以将其粘贴在那里.

  • @Rice:选项 1 仍然有效。阅读我的答案的最后一部分。此代码段不必包含在与 AJAX 代码相同的脚本文件中。无论定义在哪里,所有 JS 代码都在相同的全局范围内进行评估。 (2认同)

Jam*_*rgy 11

只要你不关心asp.net 虚拟目录(这实际上不可能从脚本中找出来,你必须从服务器传递一些东西),你可以查看URL并解析它:

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

然后:

...
   url: baseUrl()+"Controls/ModelSelectorWebMethods.aspx/getDeviceTypes",
...
Run Code Online (Sandbox Code Playgroud)

...现在我从上面的评论中看到虚拟目录是个问题.我通常这样做.

1)在你的母版页中,放置代码以在某处注入脚本,最好在其他任何东西之前(我通过添加控件而不是使用ScriptManager将它直接添加到HEAD)以确保它在任何其他脚本之前运行.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
Run Code Online (Sandbox Code Playgroud)

2)更改baseUrl以包括:

function baseUrl() {
   var href = window.location.href.split('/');
   return href[0]+'//'+href[2]+basePath;
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*ola 5

创建应用程序根变量...

var root = location.protocol + "//" + location.host;
Run Code Online (Sandbox Code Playgroud)

当您发出 AJAX 请求时,请使用绝对 URI(而不是相对 URI)...

url: root + "/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes"
Run Code Online (Sandbox Code Playgroud)