【问题标题】:Getting hash parameters from request url从请求 url 获取哈希参数
【发布时间】:2011-11-07 06:55:42
【问题描述】:

我有这样的网址 - http://www.coolsite.com/daily-plan/#id=1 解析该字符串并读取哈希值(#id= 之后的值)的最简单方法是什么? 谢谢

【问题讨论】:

  • 看看这个。基本上# 之后的任何内容都不会发送到服务器,因此它对此一无所知。这个人所做的是在处理请求的服务器端点中注入一些 javascript,然后从 URL 中获取数据并将其发送回服务器 github.com/sosodev/twitchOAuth/blob/main/twitchoauth.go#L28

标签: javascript


【解决方案1】:

在客户端(即来自 JavaScript),您可以检查 window.location.hash 以获取哈希值。在服务器端,一般的答案是“不可能”,因为哈希不会在请求中发送到服务器。

更新:我可能误解了这个问题。我的答案是关于如何在请求处理期间在浏览器或服务器端代码中获取 url 的哈希部分,而不是关于字符串处理。

Upd2:在此回复评论,因为它不适合评论。

当用户点击您的导航链接时,它是如何工作的?

我假设哈希已更改,并且相应的内容是通过来自 Web 服务或 REST 的 AJAX 请求下载的。

例如,如果您的用户在其浏览器中有 URL www.example.com,并且此页面显示产品类别列表。用户单击一个类别,URL 更改为 www.example.com/#id=5,该类别的产品(ID=5)通过 AJAX 下载并显示在页面上。没有回发,只有部分页面刷新。

这接近你的场景吗?

现在您希望用户直接在浏览器地址栏中粘贴/输入 www.example.com/#id=5 并直接转到该类别中的产品列表。

但是 /#id=5 不会被浏览器随请求发送到服务器,因此无法在服务器端获取该值,因此您无能为力,因为它是浏览器决定不发送此数据,而您在服务器端没有它。

在我们的项目中,当服务器只返回常见的页面代码/html,即页眉、页脚,没有页面的主要/中心部分时,我们使用解决方案。然后有一个 JavaScript 代码,它会在这个常见的 HTML 加载后立即执行。它接受window.location.hash 并通过 AJAX 将其发送到 Web 服务,Web 服务返回页面主要部分的内容 (HTML)。

【讨论】:

  • 让我解释一下:我做了一些带有 ajax 导航的网站。后来,我决定使用 jQuery BBQ 库,以便有机会存储浏览器历史中的所有步骤。现在我想创建这样的东西 - 如果用户转到默认页面 - 正在生成一些列表。如果他要去 /#id=5 服务器应该生成另一个内容。所以我的问题是我无法在服务器端读取#id 的值。
  • 我已经在 UPD2 中回答了。
  • 感谢 Kyrill,我遇到了与您描述的完全相同的问题。在您的解决方案中,我不喜欢对服务器的双重或三重 AJAX 请求,但显然它是一个单一的解决方案。谢谢
【解决方案2】:
new URI("http://.../abc#xyz").getFragment();

Javadocs for URI

【讨论】:

  • 嗯,但你首先如何获得/abc#xyz
  • 这个问题,正如最初提出的那样,没有提到关于客户端/服务器/浏览器或其他任何内容。它只是说你有这个URL字符串,你如何提取片段,这是我的答案涵盖的内容。
  • 从技术上讲,是的,很公平。但这只是一个字符串操作¯\_(ツ)_/¯
【解决方案3】:

这是捕获锚链接的方法。适用于所有 Web 框架。

我将使用一个示例场景来说明:假设我们需要捕获未经身​​份验证的用户请求的深层 URL http://server.com/#/xyz,以便他们可以重定向到该深层登录后网址。

  1. 未经身份验证的用户请求http://server.com/#/xyz(从“#”开始的所有内容都不会发送到服务器)。

  2. 服务器所知道的只是用户想要http://server.com/ 并且他们未经身份验证。服务器将用户重定向到登录表单。

  3. 这是一个聪明的地方:客户端仍在等待他们的原始请求,所以如果服务器在登录表单中包含一个隐藏元素,其中包含一些引用 window.location.href 的 JS,它可以捕获完整的 URL 原始请求与锚部分一起完成:

    <form action="/login" method="post">
      <div>
        <label>Username:</label>
        <input type="text" name="username"/><br/>
      </div>
      <div>
        <label>Password:</label>
        <input type="password" name="password"/>
      </div>
      <!-- XXXXXXXXX CLEVER BIT XXXXXXXXXX-->
      <script>
        document.write('<input type="hidden" name="from" value="'+document.location.href+'"/>');
      </script>
      <!-- XXXXXXXXXX-->
      <div>
        <input class="submit-button" type="submit" value="Submit"/>
      </div>
    </form>
    
  4. 用户对自己进行身份验证,原始 URL 与 POST 一起发送。然后,服务器可以将用户中继到原始深层 URL。

【讨论】:

    【解决方案4】:
    String url = " http://www.coolsite.com/daily-plan/#id=1";
    int sharpPos = url.indexOf('#');
    String q = null;
    if (sharpPos >= 0) {
        q = url.substring(sharpPos);
    }
    

    当然,您可以使用各种字符串操作方法,包括正则表达式。

    但实际上你的例子很奇怪。通常 URL 的参数在问号之后传递。在这种情况下,您可以只使用标准类 URL:

    String q = new URL(" http://www.coolsite.com/daily-plan?id=1").getQuery();

    【讨论】:

    • 我同意通常我看到在问号之后传递的参数。然而,有时我看到它是作为哈希完成的......但很少和更复杂的代码。
    【解决方案5】:

    你用什么来做这个?

    如果您使用的是 jsp 或 servlet,以下内容对您很有用

    if (request.getParameter("#id") == null) {
        out.println("Please enter your name.");
    } else {
        out.println("Hello <b>"+request.getParameter(i)+"</b>!");
    }
    

    如果您使用 javascript,以下功能将对您有用

    function getURLParameters() 
    {
    var sURL = window.document.URL.toString();
    
    if (sURL.indexOf("?") > 0)
    {
        var arrParams = sURL.split("?");
    
        var arrURLParams = arrParams[1].split("&");
    
        var arrParamNames = new Array(arrURLParams.length);
        var arrParamValues = new Array(arrURLParams.length);
    
        var i = 0;
        for (i=0;i<arrURLParams.length;i++)
        {
            var sParam =  arrURLParams[i].split("=");
            arrParamNames[i] = sParam[0];
            if (sParam[1] != "")
                arrParamValues[i] = unescape(sParam[1]);
            else
                arrParamValues[i] = "No Value";
        }
    
        for (i=0;i<arrURLParams.length;i++)
        {
            alert(arrParamNames[i]+" = "+ arrParamValues[i]);
        }
    }
    else
    {
        alert("No parameters.");
    }
       }
    

    【讨论】:

    • 服务器端好像没有办法读取hash变量
    • 如果你想在服务器端读取它,servlet 可以这样做,它会在服务器端提供参数,如第一个 code-sn-p 所示。您将在您的 servlet 中获得 HttpRequest 对象请求,通过它您可以获取它的参数。
    • request.getParameter("#id"), request.getAttribute("#id") 不起作用。
    • 它给出了什么错误?这段代码 sn-p 是在哪里写的?
    • 没有任何错误。它返回空值。我正在使用 Spring MVC。所以我试图在控制器方法中获取请求参数
    【解决方案6】:

    在解析 url 时将 '#' 替换为 '?'。检查下面的代码

    String url = "http://www.coolsite.com/daily-plan/#id=1";
    String urlNew = url.replace("#", "?");
    String id = Uri.parse(urlNew).getQueryParameter("id");
    

    【讨论】:

    • 这段代码显然不尊重 url 中已经存在的查询参数的可能性......我建议反对这个解决方案,因为它滥用了一个概念并且只适用于特殊情况。
    【解决方案7】:

    如果您的 URL 与您编写的相同,并且不包含任何其他内容,那么 Java 上的 whis 代码将为您提供帮助

     String val = "http://www.coolsite.com/daily-plan/#id=1";
     System.out.println(val.split("#id")[1]);
    

    不要忘记检查空值。

    附:如果你使用 servlet,你可以从 request.getAttribute("id") 获取这个参数。

    谨此致以最诚挚的问候, 心理

    【讨论】:

    • request.getParameter("#id"), request.getAttribute("#id") 不起作用
    • 您无法在 servlet 上获取参数,因为您的 url 不正确示例是 coolsite.com/daily-plan/?id=1" 那么我的示例代码将起作用并为您提供参数。( request.getAttribute("id "))
    • 我知道我的网址不正确。实际上它是正确的,但是传递参数是不正确的。所以我的问题是 - 有没有办法在服务器端读取该#id 参数
    • 否,该参数默认不发送到服务器。字节您只能在客户端获取此参数并手动将其发送到服务器。你怎么称呼你的servlet? html格式?还是调用jQuery方法?
    • 问题是我正在使用 jQuery BBQ 插件来启用浏览器的后退按钮。但是当我第一次调用该页面时 - 内容已经在服务器端生成。
    【解决方案8】:

    如果您的 url 从 OAuth 回调中获取,那么您不能! 因为完整的 url 不会发送到服务,因为 hash(#)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2017-04-14
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 2012-05-28
      • 2011-04-20
      相关资源
      最近更新 更多