JavaScript中的~ /等价物

43

有没有一种聪明的方式在JavaScript中进行基于“根”路径引用,就像ASP.NET中的~/一样?


你正在为什么构建路径?XmlHttpRequest? - harpo
@Gumbo:它指的是应用程序根目录,与asp.net相关。 - Brian
12个回答

46

让你的页面生成一个类似以下内容的标签:

<link rel="home" id="ApplicationRoot" href="http://www.example.com/appRoot/" />

然后,在JavaScript中编写一个提取值的函数,例如:

function getHome(){
    return document.getElementById("ApplicationRoot").href;
}

1
稍微修改了示例,使其不那么模糊。 - BenAlabaster
注意:要生成标记,可以使用以下代码:string urlPath = HttpContext.Current.Request.Url.Scheme + "://”+HttpContext.Current.Request.Url.Authority+HttpContext.Current.Request.ApplicationPath; - Brian
5
如果你要使用服务器端代码来生成值,为什么需要将它放在<link>元素中并通过getElementById检索它呢?只需这样做:<script>var home = '<%= HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.ApplicationPath %>';</script> - Grant Wagner
3
把它放在 <link> 标签中可以使 JS 与标记分离。当然,Web 表单会将相当多的 JS 强制加入您的标记,因此在那种环境下使用这个变量可能更容易些。 - AaronSieb
1
<link id="ApplicationRoot" href="~/" rel="home" /> 提供了一个不错的相对路径前缀。请注意,head标签必须具有runat="server"属性。 - Richard Collette

39

使用base标签:

<head>
   <base href="http://www.example.com/myapp/" />
</head>

从现在开始,此页面上使用的所有链接(包括 JavaScript 和 HTML 中的)都将相对于基准标签而言,该基准标签为 "http://www.example.com/myapp/"。


真的很有用。我不知道这个标签。 - Vikram
1
太棒了,以前不知道这个标签。请参考下面Nilzor的答案,进行动态增强。非常适合在开发和测试环境中具有不同URL的兼容性。 - Piwaf
需要注意的是,ASP.NET Web Forms 为 CSS 链接标签等生成相对路径。应用此类基础标签会破坏这些相对路径。我更喜欢上述链接方法,而不是 JS 变量,因为当 URL 被网络基础设施设备(如 F5 BIGIP)重写时,JS 变量有时会被忽略。href 属性是这些设备可以轻松识别的明显 URL。 - Richard Collette
3
请注意,使用base标签可能也会存在问题,请参见[https://dev59.com/enI-5IYBdhLWcg3wYXL8]。 - anre

11

你还可以使用 asp.net 的 VirtualPathUtility 功能:

<script>
var basePath = '<%=VirtualPathUtility.ToAbsolutePath("~/")%>';
</script>

注意:我没有对路径进行编码为JSON字符串(转义引号、控制字符等)。我认为这不是一个大问题(例如,引号在URL中未经转义是不允许的),但谁也不能确定...


4
方法应该是:VirtualPathUtility.ToAbsolute("~/")这是最佳方法,因为它具有更大的灵活性,可以部署为虚拟目录或根 Web 应用程序。 - Manuel Castro

8

我通常在js文件的顶部创建一个变量,并将根路径分配给它。然后在引用文件时使用该变量。

var rootPath = "/";
image.src = rootPath + "images/something.png";

6

~/是应用程序的根目录,而不是字面上的根目录,它将解释~/为<YourAppVirtualDir>/

在JavaScript中,要使用字面上的根目录只需使用 / ,例如 "/root.html"。没有办法在JavaScript中获取应用程序级别的路径。

您可以在ASPX文件中进行修改,并在标记中输出它,但我建议考虑其安全性影响。


虽然你对~/的定义是正确的,但说没有办法通过JavaScript获取它有点失败主义,只需要一点想象力就可以了。 - BenAlabaster
好的,其中一个完全是服务器端的,而另一个不是,尽管我说过你可以将它带到客户端,但我个人不会这样做 :) - Lloyd
将应用程序根目录暴露出来可能会有什么安全隐患?攻击者已经知道应用程序根目录是页面URL的嵌套级别之一,不是吗? - AaronSieb
是的,我在考虑 ~/ 最终会被展开,但这不会发生。 - Lloyd

6

Kamarey的答案可以改进,以支持动态基路径:

<head>    
      <base href="http://<%= Request.Url.Authority + Request.ApplicationPath%>/" />    
</head> 

这将确保正确的根路径,无论部署配置如何。
公正地说,这并没有回答原始问题,但它消除了大多数需要从Javascript获取根路径的需求。在任何地方使用相对URL而不带斜杠前缀即可。
如果仍然需要从Javascript访问它,请添加id属性并在基本标签上使用document.getElementFromId(),就像MiffTheFox建议的那样。

我喜欢这个解决方案,但是我必须稍微调整一下才能让它在Razor中起作用。 <base href="http://@((Request.Url.Authority + Request.ApplicationPath).TrimEnd('/'))/" /> ApplicationPath有时以“ /”结尾,有时则没有,所以我添加了TrimEnd('/')调用。 - DanielC

5
另一个更简单和普遍的选择是采取以下措施:
<script src="/assets/js/bootstrap.min.js"><script>

并使用Page.ResolveClientUrl,如下所示:

<script src='<%=ResolveClientUrl("~/assets/js/bootstrap.min.js")%>'></script>

那么无论URL在哪个子目录下,它们都将正确呈现。

2
下面的函数将计算当前运行应用程序的根。当从应用程序树的深处调用时,我使用它来定位资源的绝对位置。
    function AppRoot() {
        //
        // Returns the root of the currently running ASP application.
        // in the form: "http://localhost/TRMS40/"
        //
        //   origin: "http://localhost"
        // pathname: "/TRMS40/Test/Test%20EMA.aspx"
        //
        // usage:
        //           window.open( AppRoot() + "CertPlan_Editor.aspx?ID=" + ID);
        //

        var z = window.location.pathname.split('/');

        return window.location.origin + "/" + z[1] + "/";
    }

2

ASP.NET MVC应用程序的解决方案

在使用IIS和VS中的IIS Express时,此方法有效。

将此代码片段放置在所有脚本加载之前,以便具有根URL变量“approot”。

在脚本中可使用此服务:

<script>
        var approot = "@Url.Content("~")";
</script>

 --> other scripts go here or somewhere later in the page.

然后在您的脚本或页面脚本中使用它。 示例:

var sound_root_path = approot + "sound/";
var img_root_path = approot + "img/";

appproot变量的值可能是:

"/YourWebsiteName/" <-- IIS

或者只是:

"/" <-- IIS Express


1
在您的.NET基础页面的PreRender中添加以下内容:
 protected override void
 OnPreRender(EventArgs e) {
     base.OnPreRender(e);

     if (Page.Header != null)
     {
         //USED TO RESOLVE URL IN JAVASCRIPT
         string baseUrl = String.Format("var baseUrl='{0}';\n", 
           HttpContext.Current.Request.ApplicationPath);
         Page.Header.Controls.Add(new LiteralControl(String.Format(Consts.JS_TAG,
           baseUrl)));
     }
}

然后在你的全局JavaScript函数中添加以下内容:

 function resolveUrl(url) {
   if (url.indexOf("~/") == 0) {
     url = baseUrl + url.substring(2);
   }
 return url; }

现在你可以像这样使用它:

 document.getElementById('someimage').src = resolveUrl('~/images/protest.jpg');

对于一些小型项目来说可能有点过于繁琐,但对于完整的应用程序非常有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接