【问题标题】:Get final url from XHR object after redirect重定向后从 XHR 对象获取最终 url
【发布时间】:2013-05-02 02:33:23
【问题描述】:

假设我使用 ajax(例如通过 jQuery)向实现 PRG 模式的 API 发出 POST 请求。因此它会重定向我:

POST /some/api
HTTP/1.1 303 See Other
Location: /some/other/location

jQuery 会自动跟随重定向并执行:

GET /some/other/location

然后使用后一个请求的输出调用响应处理程序(成功、失败等)。但是,如何在 javascript 中读取最终资源的位置(在本例中为 /some/other/location)?

【问题讨论】:

  • this answer报道,目前正在最新的浏览器中实现。

标签: jquery ajax redirect


【解决方案1】:

虽然这是一篇旧帖子,但希望这个更新的(2018 年)答案会对某人有所帮助。请注意,此解决方案不适用于 Internet Explorer(任何版本),仅适用于其他浏览器的相对现代版本。

XMLHttpRequest 现在公开了一个名为 responseURL 的只读属性,它在发生任何重定向后返回响应的 URL。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com', true);
xhr.onload = function () {
  console.log(xhr.responseURL); // Prints http://example.com
};
xhr.send();

请参阅https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseURL 的文档

【讨论】:

    【解决方案2】:

    这是一篇旧帖子,但它在 Google 中排名很高,所以我将添加我的解决方案。

    如果您可以控制 ajax 响应,则可以将标头添加到带有最终 URL 的响应中。

    在 PHP 中是这样的:

    header('X-final-url: /some/other/location').

    然后,在 jquery 中,您可以通过以下方式访问该值:

    var finalUrl = jqXHR.getResponseHeader('X-final-url');

    我在 Symfony 中添加了带有内核侦听器的标头:

    服务

    app.kernel.response_metadata_populator:
        class: AppBundle\Listeners\ResponseMetadataPopulator
        tags:
            - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
    

    监听类

    class ResponseMetadataPopulator
    {
        /**
         * @param FilterResponseEvent $event
         */
        public function onKernelResponse(FilterResponseEvent $event)
        {
            $response = $event->getResponse();
            $response->headers->set('X-FINAL-URL', $event->getRequest()->getRequestUri());
        }
    }
    

    【讨论】:

      【解决方案3】:

      XMLHttpRequest 不会公开最终 URL。

      :[

      但是,您可以在不使用 iframe 的情况下解决这个问题。如果要返回 JSON 对象,则可以添加 finalURL 属性,如下所示:

      { "finalURL": "http://example.com/API/v2/request.json", "response": {...} }
      

      并阅读以获取重定向后的 URL。希望对您有所帮助!

      【讨论】:

        【解决方案4】:

        据我所知,XMLHttpRequest 对象是不可能的。但是,如果您在您的 [受信任] 域中操作,并且它是重要信息,您可以使用 iframe 代替:

        var hidden_iframe = document.createElement('iframe');
        hidden_iframe.name = 'hidden_iframe';
        hidden_iframe.style.display = 'none';
        hidden_iframe.onload = function() {
          console.log(hidden_iframe.contentWindow.location.toString());
        }
        document.body.appendChild(hidden_iframe);
        
        var request = document.createElement('form');
        request.method = 'post';
        request.action = '/some/api';
        request.target = 'hidden_iframe';
        request.style.display = 'none';
        
        // append INPUTs to the request form here
        
        document.body.appendChild(request);
        request.submit();
        

        您的控制台应该报告 1 个或多个 URL,其中最后一个是:

        http(s)://{yourdomain}/some/other/location

        【讨论】:

        • 感谢您的建议。使用框架而不是 XMLHttpRequest 在事件处理等方面有点麻烦。但在某些情况下它可能很有用。
        【解决方案5】:

        我相信这通常是不可能的,尽管我可以通过 Chrome 开发者工具看到浏览器确实从服务器获得 303 响应,然后遵循重定向。

        查看此相关问答:Is it possible for XHR HEAD requests to not follow redirects (301 302)

        【讨论】:

          猜你喜欢
          • 2011-03-05
          • 2021-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          • 2022-09-28
          • 2017-07-11
          相关资源
          最近更新 更多