【问题标题】:How to get relative path in Javascript?如何在Javascript中获取相对路径?
【发布时间】:2011-09-12 17:29:30
【问题描述】:

在我的 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;
}

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

【问题讨论】:

  • 你试过绝对路径吗? /widget/Controls/...
  • 我想我可以使用绝对路径,但这会破坏我不使用虚拟目录 /widget 的开发服务器...
  • 请不要使用async: false,您的用户会讨厌您锁定他们的浏览器。改为指定回调。我手头唯一的资源是stackoverflow.com/questions/2956261/…,但快速的 Google for AJAX 回调将帮助您加载。

标签: javascript jquery asp.net ajax


【解决方案1】:

你有两个选择:

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

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

    然后在 AJAX url 前面加上 config.base(并更改 config.base 的值,无论您是在开发/测试/部署服务器上。)

  2. 使用&lt;base /&gt; HTML 标记为所有相对 URL 设置 URL 前缀。这会影响所有相对 URL:图片、链接等。

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

显然,配置对象必须包含在您的站点中评估服务器端代码的部分中; .js 文件不会在不配置服务器的情况下剪切它。我总是在 HTML &lt;head&gt; 中包含配置对象;它是一个小的配置对象,其内容可以在每个页面上更改,因此完全可以将其粘贴在其中。

【讨论】:

  • 选项 1 在这里不起作用,因为此代码在外部 JS 文件中
  • @Rice:选项 1 仍然有效。阅读我答案的最后一部分。这个 sn-p 不必包含在与 AJAX 代码相同的脚本文件中。所有 JS 代码都在同一个全局范围内进行评估,无论它是在哪里定义的。
【解决方案2】:

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

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

然后:

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

...现在我从您上面的 cmets 看到虚拟目录是个问题。我通常这样做。

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

2) 更改 baseUrl 以包括:

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

【讨论】:

    【解决方案3】:

    创建应用根变量...

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

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

    url: root + "/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes"
    

    【讨论】:

      【解决方案4】:

      我认为这个功能会起作用...它是获取相对路径为“../../../” 所以如果你在每个页面中调用这个函数,这将返回一个相对路径格式。

      function getPath() {
          var path = "";
          nodes = window.location. pathname. split('/');
          for (var index = 0; index < nodes.length - 3; index++) {
              path += "../";
          }
          return path;
      }
      

      【讨论】:

        【解决方案5】:

        可以在开头导入命名空间: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>
        

        【讨论】:

          【解决方案6】:

          你能用window.location.pathname吗?

          var pathname = window.location.pathname;
          $.ajax({
              //...
              url: pathname + 'Controls/...', // might need a leading '/'
              //...
          });
          

          【讨论】:

          • 这会解决JS文件放错地方的问题,但是如果实际的页面不是从根目录加载的话就会中断。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-06-03
          • 2010-09-21
          • 2021-12-13
          • 1970-01-01
          • 2011-07-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多