【问题标题】:Ajaxical redirect using query-string parameters使用查询字符串参数的 Ajaxical 重定向
【发布时间】:2016-07-03 17:03:45
【问题描述】:

使用以下部分响应进行重定向(在 Servlet 过滤器内)。当用户成功登录时,它会尝试重定向到目标资源。

private void redirect(HttpServletRequest request, HttpServletResponse response, String redirectURL) throws IOException {
    if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
        response.setContentType("text/xml");
        response.setCharacterEncoding("UTF-8");
        response.getWriter()
                .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
                .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", redirectURL);
    } else {
        response.sendRedirect(response.encodeRedirectURL(redirectURL));
    }
}

请求/响应标头:

General

    Request URL:https://localhost:8443/ContextRoot/utility/Login
    Request Method:POST
    Status Code:302 Found
    Remote Address:127.0.0.1:8443

Response Headers

    Cache-Control:no-cache, no-store, must-revalidate
    Connection:keep-alive
    Content-Length:0
    Date:Thu, 17 Mar 2016 11:12:58 GMT
    Expires:Thu, 01 Jan 1970 00:00:00 GMT
    Location:https://localhost:8443/ContextRoot/admin/Home.xhtml
    Pragma:no-cache
    Server:WildFly/10
    X-Powered-By:Undertow/1

Request Headers

    Accept:application/xml, text/xml, */*; q=0.01
    Accept-Encoding:gzip, deflate
    Accept-Language:en-US,en;q=0.8
    Connection:keep-alive
    Content-Length:256
    Content-Type:application/x-www-form-urlencoded; charset=UTF-8
    Cookie:JSESSIONID=0a-fKcNyfWx_Cu30m5fZUusrQ4g-qbHqhvojrNCU.om-f6b0ea3ad206; __utma=111872281.616526714.1454485589.1454485589.1454485589.1; __utmz=111872281.1454485589.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
    Faces-Request:partial/ajax
    Host:localhost:8443
    Origin:https://localhost:8443
    Referer:https://localhost:8443/ContextRoot/admin/RatingDetails?product=10&id=2
    User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
    X-Requested-With:XMLHttpRequest

Form Data

    view URL encoded
    javax.faces.partial.ajax:true
    javax.faces.source:login
    javax.faces.partial.execute:loginForm
    javax.faces.partial.render:loginForm
    login:login
    loginForm:loginForm
    userName:admin
    password:admin
    javax.faces.ViewState:-5804174403308424993:4075605247268615317

可以看出,响应状态码是“302 Found”,但是没有重定向到目标资源。

罪魁祸首是查询字符串中的&amp;

https://localhost:8443/ContextRoot/admin/RatingDetails?product=10&id=2

带有单个查询字符串参数的以下内容可以正常工作:

https://localhost:8443/ContextRoot/admin/RatingDetails?product=10

有一个解析错误:

<partial-response>
    <parsererror style="display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black">
        <h3>This page contains the following errors:</h3>
        <div style="font-family:monospace;font-size:12px">error on line 1 at column 118: EntityRef: expecting ';'
        </div>
        <h3>Below is a rendering of the page up to the first error.</h3>
    </parsererror>
</partial-response>

response.encodeURL(redirectURL)response.encodeRedirectURL(redirectURL) 在这种情况下也无济于事。

有什么建议吗?

【问题讨论】:

    标签: ajax jsf redirect


    【解决方案1】:

    第 1 行第 118 列的错误:EntityRef: 期待 ';'

    &amp;amp; 是 XML 中的一个特殊字符,表示实体的开始,它应该以 ; 字符结尾,例如&amp;lt;&amp;#xA0; 等。这解释了错误消息的那一部分。

    但是,您使用该字符作为查询字符串参数分隔符,没有任何实体引用名称和结束字符 ;。因此,XML 解析器会失败。

    &amp;amp; 转义为&amp;amp; 应该可以解决它。重定向 URL 必须以这种格式结束:

    https://localhost:8443/ContextRoot/admin/RatingDetails?product=10&amp;id=2
    

    encodeURL()/encodeRedirectURL() 用于不同的目的,In the context of Java Servlet what is the difference between URL Rewriting and Forwarding? 中对此进行了解释

    另见:

    【讨论】:

    • 这些参数在运行时使用&lt;o:viewParam name="product" .../&gt;&lt;o:viewParam name="id" .../&gt;动态附加。因此,&amp;amp; 会自动插入到查询字符串中传递的每个键/值对参数之间。根据传递的参数数量,&amp;amp; 可能存在也可能不存在。在Servlet过滤器中从redirectURL抓取查询字符串后是否需要手动转义&amp;amp;
    • redirectURL 究竟从何而来?
    • 在一种情况下:URL 是一个后备或返回 URL,它本身作为查询字符串参数附加:(在 &lt;p:link&gt; 内),&lt;f:param name="fallback" value="#{request.requestURI}#{not empty request.queryString? '?' : ''}#{request.queryString}"/&gt;,在另一种情况下:获取 URL通过context.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI)context.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING)
    • 我认为无论如何我都必须做类似redirectURL.replaceAll("&amp;", "&amp;amp;") 这样的事情。
    • 归根结底,是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多