重定向后从XHR对象获取最终URL

时间:2013-05-08 00:46:29

标签: jquery ajax redirect

假设我使用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)的位置?

5 个答案:

答案 0 :(得分:5)

据我所知,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();

您的控制台应报告一个或多个网址,其中最后一个网址为:

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

答案 1 :(得分:4)

XMLHttpRequest不公开最终的URL。

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

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

并阅读以获取后重定向网址。希望这有用!

答案 2 :(得分: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

中的文档

答案 3 :(得分:0)

我认为一般情况下这是不可能的,虽然我可以通过Chrome开发者工具看到浏览器确实从服务器获得303响应然后跟随重定向。

请参阅此相关问题和答案:Is it possible for XHR HEAD requests to not follow redirects (301 302)

答案 4 :(得分:0)

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

如果您可以控制ajax响应,则可以使用最终网址为响应添加标题。

在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());
    }
}
相关问题