如何在servlet中设置URL锚点(哈希)?

5

简单的问题!不知道为什么谷歌不知道答案!

在Java servlet中,我如何设置返回给用户时的URL锚点(哈希)?


1
什么时候返回?Servlet通常返回HTML页面,或者作为JSON或XML的数据。它不会返回URL,除非进行重定向。如果需要,您可以将哈希添加到重定向URL中。它只是一个字符串。如果您的目标是更改客户端请求的资源的URL,则无法实现。只有客户端可以这样做。 - JB Nizet
@JBNizet 当返回HTML时,我想要最简单的情况。我担心重定向是否会有其他影响或副作用? - Ali Moosavi
就像我说的那样,你不能这样做。服务器无法执行该操作。 - JB Nizet
1
重定向请求不起作用,因为它会导致重定向循环。/someurl 是与 /someurl#hash 相同的服务器路径。 - jHilscher
2个回答

5

URL锚点仅由浏览器处理,甚至不会到达服务器(它不是请求的一部分)。

这意味着在服务器端,无论是在您建议的servlet中还是使用任何其他服务器端技术(例如PHP),您可以重定向到具有URL锚点设置的URL,但您无法检查当前处理的请求中是否提供了URL锚点。

此限制防止您在保持其余URL不变的情况下设置URL锚点,因为服务器无法区分具有和不具有URL锚点的地址。

因此,您可以执行以下操作:此答案的规范地址是:

https://dev59.com/gYbca4cB1Zd3GeqPcvnV#27988314

但是服务器将它重定向到这里

https://dev59.com/gYbca4cB1Zd3GeqPcvnV#27988314

请注意,锚点之前的URL部分不同。
在HTTP servlet中,您可以通过使用传递给服务方法的HTTPServletResponse对象的sendRedirect(String)方法来实现此目的,例如:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {

    /* ... */

    response.sendRedirect("http://example.com/your/url#hash");
}

然而,你不能做到这一点:重定向此页面。
http://example.com/some/url

转换为这样

http://example.com/some/url#there

就服务器而言,这两个地址是相同的,服务器无法区分它们。这使得检查地址是否为第一个地址(即没有URL锚点的地址)并有条件地进行重定向成为不可能。未经检查就进行重定向,当然会创建一个重定向循环。
然而,根据您确切想要实现的内容,即使在您的servlet中不能完成,您也可以使用客户端脚本(如JavaScript)来实现它。请查看window.location.hash属性。

我不想读取接收到的URL锚点。 我希望在返回给用户时设置URL锚点。 - Ali Moosavi
@AliMoosavi 我明白了。请看一下我的修订答案,我认为现在更清晰了。 - Philippe Aubertin

0

我曾经遇到过类似的需求。

我的问题是:

在同一个jsp页面上有两个不同的表单(一个用于注册,一个用于登录)。这些表单通过url中的哈希值进行显示,例如http://myapp.com/auth#login 显示登录表单,http://myapp.com/auth#signup 显示注册表单。

我需要通过重新加载同一页面向用户显示验证错误,但无法从我的servlet导航到哈希值。

以下是我如何显示验证错误(jsp):

    <form method="post" action="authentication">
        <c:forEach items="${errorSignupMessage}" var="message">
            <div class="error-message">${message}</div>
        </c:forEach>
          ..................................
    </form>

errorSignupMessage是我通过servlet传递的属性

request.setAttribute("errorSignupMessage", array);

解决方案:

首先,在我的表单中创建了一个隐藏字段,该字段必须包含所需的属性:

<input type="text" name="ACTION" class="hidden  important" value="signup" data-attr="${errorSignupMessage != null ? true : false}"/>

需要注意的是属性data-attr。正如您所看到的,我根据servlet的操作在属性上设置了布尔值,即如果errorSignupMessagenull,则用户与另一个表单交互,如果errorSignupMessage存在且不为null,则当前表单是用户交互的表单。

然后我转到javascript,并使用window.onload事件进行数据属性检测并编写一些逻辑以更改location.hash值。

var authForms = document.getElementsByClassName('important');
function changeHash() {
    for(var i = 0; i < authForms.length; ++i) {
        var form = authForms[i];

        if (form.value === 'signup' && form.getAttribute('data-attr') === 'true') {
            location.hash = '#signup';
        } else {
            location.hash = '#login';
        }
    }
}
window.onload = changeHash;

这就是我解决问题的方法。当然,你需要根据自己的需求进行调整,但我认为你仍然可以得到一般的想法。

希望对你有所帮助!


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