【问题标题】:How do you get the contextPath from JavaScript, the right way?如何以正确的方式从 JavaScript 中获取 contextPath?
【发布时间】:2011-09-30 17:36:17
【问题描述】:

使用基于 Java 的后端(即 servlet 和 JSP),如果我需要来自 JavaScript 的 contextPath,那么推荐的模式是什么,为什么?我能想到几种可能性。我错过了什么吗?

1.将 SCRIPT 标记刻录到页面中,并在某些 JavaScript 变量中设置它

<script>var ctx = "<%=request.getContextPath()%>"</script>

这是准确的,但在加载页面时需要执行脚本。

2。在一些隐藏的 DOM 元素中设置 contextPath

<span id="ctx" style="display:none;"><%=request.getContextPath()%></span>

这是准确的,加载页面时不需要执行任何脚本。但是当需要访问 contextPath 时,您确实需要一个 DOM 查询。如果您非常关心性能,则可以缓存 DOM 查询的结果。

3.尝试通过检查 document.URL 或 BASE 标记在 JavaScript 中找出答案

function() {
    var base = document.getElementsByTagName('base')[0];
    if (base && base.href && (base.href.length > 0)) {
        base = base.href;
    } else {
        base = document.URL;
    }
    return base.substr(0,
        base.indexOf("/", base.indexOf("/", base.indexOf("//") + 2) + 1));
};

这在加载页面时不需要执行任何脚本,如果需要,您还可以缓存结果。但这仅在您知道上下文路径是单个目录时才有效——而不是根目录 (/) 或多个目录 (/mypath/iscomplicated/)。

我往哪个方向倾斜

我更喜欢隐藏的 DOM 元素,因为它不需要在页面加载时执行 JavaScript 代码。只有当我需要 contextPath 时,我才需要执行任何操作(在这种情况下,运行 DOM 查询)。

【问题讨论】:

  • 我一生都无法理解为什么“但在加载页面时需要执行脚本” 是一个如此大的问题,以至于您宁愿回退到 DOM 摆弄/遍历。你能详细说明一下吗?另外,你到底需要什么上下文路径?也许还有其他方法让你根本不需要它。
  • 加载页面时执行 JavaScript 会阻止并行下载。也许单线没关系。 DOM 遍历可能更具惩罚性,但至少您可以选择延迟惩罚,直到您绝对需要它(如果您需要它)。我不确定按 ID 查找是否会受到惩罚。
  • 我自己不需要 contextPath。我只是提出了一个“如果”。这是一个可能的例子:我正在动态加载一个 JS 文件并且需要知道它的路径。如果我提前知道 contextPath,我可以使用绝对路径,但是如果 contextPath 发生变化,那么我的脚本就会中断。我可以使用相对路径,但这取决于父 HTML 文档的位置。如果我移动文件,我的分页符。了解 contextPath,我可以通过动态生成的绝对路径来保护自己免受这些类型的破坏。
  • 分配一个全局变量在现代浏览器中基本上是无操作的。我一个人不会为此使用老式的 scriptlets,而只是使用 EL。 var ctx = '${pageContext.request.contextPath}';
  • @BalusC 你太棒了。感谢您总是发布您所知道的有关如何使用 JSP 的信息。另外,我无法让您的建议生效。当我将它放在脚本标签中时,无法识别 EL。当我不将它放在脚本标签中时,错误表示变量定义错误。我该怎么做您在上面发布的内容?

标签: javascript jsp servlets


【解决方案1】:

根据 cmets 中的讨论(尤其是来自 BalusC),可能不值得做比这更复杂的事情:

<script>var ctx = "${pageContext.request.contextPath}"</script>

【讨论】:

  • 虽然乏味,但我总是更喜欢让我的 JavaScript 对象接收定义“baseUrl”或上下文的属性。我将在 jsp 中有一个脚本标记来“初始化”页面的 JavaScript 对象,并将 baseUrl 传递给它们。这样我就不必假设某些全局变量可用。
  • @Mike M. Lin,如果我们使用使用 document.url 获取路径的选项是否有任何陷阱
  • 有人可以帮我吗?我在我的 javascript 文件中添加了全局变量,但它返回给我的是原始字符串“${pageContext.request.contextPath}”而不是项目的 contextPath..
  • @FelipeMosso 它进入你的 .jsp 文件,而不是你的 JavaScript 文件。
  • @MikeM.Lin 谢谢你,我稍后再试.. 标签让我觉得我应该添加到 JavaScript 文件中
【解决方案2】:

知道了:D

function getContextPath() {
   return window.location.pathname.substring(0, window.location.pathname.indexOf("/",2));
}
alert(getContextPath());

重要提示:仅适用于“根”上下文路径。不适用于“子文件夹”,或者上下文路径中有斜杠(“/”)。

【讨论】:

  • 这是最好的答案!它不会将 jsp 与 javascript 定义混合使用
  • FWIW 如果上下文路径中有斜杠(例如/foo/bar),则会失败。
  • 我看到 window.location.pathname 的值类似于“/context/p1/p2/p3.html”,所以这个建议返回“/context”。但是 Java Web 应用程序可能部署在 ROOT 上下文中,因此路径名的第一个组件不是上下文字符串。我不知道如何使用仅限客户端的脚本来处理这个问题,这是一个问题,因为我没有使用 JSP 或 Servlets。
  • 这不会返回上下文路径。这将返回 URL 的第一个路径名,不一定是上下文路径。
  • 过去两天我都遇到了这个问题。终于找到了该问题的解决方案。非常感谢@Cedric
【解决方案3】:

我认为您可以通过将数字 1 与调用数字 3 中的函数相结合来实现您正在寻找的东西。

您不想在页面加载时执行脚本并希望稍后调用函数?很好,只需创建一个函数,它会返回您在变量中设置的值:

function getContextPath() {
   return "<%=request.getContextPath()%>";
}

它是一个函数,所以在你真正调用它之前它不会被执行,但是它直接返回值,不需要做 DOM 遍历或修改 URL。

此时我同意@BalusC 使用EL:

function getContextPath() {
   return "${pageContext.request.contextPath}";
}

或取决于 JSP 的版本回退到 JSTL:

function getContextPath() {
   return "<c:out value="${pageContext.request.contextPath}" />";
}

【讨论】:

  • 很酷的想法,但这实际上会更多开销。因为现在除了变量赋值之外,我还有一个函数声明。 function getContextPath() {..} 实际上扩展为 window.getContextPath = function() {..}。在这一点上,我同意 BalusC 的观点,即 var ctx = '${pageContext.request.contextPath}'; 之类的东西没有任何问题。它尽可能接近无操作。
【解决方案4】:

通过此查看解决方案 检查此页面的解决方案,制作以下解决方案,我希望它有效: 例子:

Javascript:

var context = window.location.pathname.substring(0, window.location.pathname.indexOf("/",2)); 
var url =window.location.protocol+"//"+ window.location.host +context+"/bla/bla";

【讨论】:

    【解决方案5】:

    我使用 id="contextPahtHolder" 将上下文路径渲染到链接标签的属性,然后在 JS 代码中获取它。例如:

    <html>
        <head>
            <link id="contextPathHolder" data-contextPath="${pageContext.request.contextPath}"/>
        <body>
            <script src="main.js" type="text/javascript"></script>
        </body>
    </html>
    

    main.js

    var CONTEXT_PATH = $('#contextPathHolder').attr('data-contextPath');
    $.get(CONTEXT_PATH + '/action_url', function() {});
    

    如果上下文路径为空(如在嵌入式 servlet 容器实例中),它将是空字符串。否则它包含 contextPath 字符串

    【讨论】:

    • 不错的解决方案,在我的 Grails 应用程序和 gsp sn-p 的情况下对我有用:${request.contextPath}
    • 这项工作对我来说是使用带有百里香叶的 springboot 进行的小修改。在 HTML
    【解决方案6】:

    带有 Thymeleaf 解决方案的 Spring Boot 可能如下所示:

    假设我的上下文路径是/app/

    在 Thymeleaf 中,您可以通过以下方式获得它:

    <script th:inline="javascript">
        /*<![CDATA[*/
            let contextPath    = /*[[@{/}]]*/
        /*]]>*/
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-02
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多