ajax 遇到重定向,ajax 重定向跨域问题

最近遇到一个问题:一个页面发 ajax 请求到后端接口,这个后端接口返回 302 状态码,并重定向了另外一个域名的地址,此时出现跨域问题

ajax 调用浏览器组件发起的请求和浏览器直接发起的请求有一定区别。

1.浏览器可以通过返回的 http 状态进行相应的操作,如访问一个页面,此页面重定向时,浏览器可以获取到重定向后的 url 然后进行转向。

2.对于 ajax,ajax 的目的就是无刷新的,所以对于服务器端进行了重定向时,ajax 会获取到重定向状态值 3xx 和重定向 url,然后再获取重定向的页面运行完后输出到客户端的 html 代码,并且返回 200 状态。

上面的场景:

1.如果是浏览器发送请求到后端接口,后端接口重定向的话是给浏览器一个 302 的标示,并且给一个 url,浏览器拿到标示后会把地址栏的 url 换成后端返回的 url,完成重定向动作。

2.如果是 ajax 的话,请求后端接口,后端返回 302 和一个 url,那么 ajax 会根据 htpp 的 code 码做出相对应的动作。接受到的是 302 那么 ajax 会再次发起一个请求,去请求服务端 302 返回的 url,那么此时就跨域了。

解决的方式是 ajax 在第一次得到相应处理后需要 js 做一次 location.href 跳转,目的是让浏览器去请求重定向的接口而不是 ajax。

于是我就开始想如何将 302 拦截下来,自己做 location.href 跳转,由于我的项目用到了 axios,我在 axios 的响应拦截器axios.interceptors.response中开始进行处理,但是怎么都得不到对应的 302 返回结果,最后搜到了这篇文章。

文章中提到了这个属性maxRedirects1

2

3

4

5

6

// `maxRedirects` defines the maximum number of redirects to follow in node.js.

// If set to 0, no redirects will be followed.

{

maxRedirects: 5, // default

}

我尝试去修改了这个属性,然而并没有实际效果,后来又搜到了这篇 issue。

文章中提到在 axios 取到 xhr 的响应前,客户端已经完成了重定向的操作。

Client side redirect is being done before axios ever get any response from XHR.

You can’t handle redirects with XHR callbacks because the browser takes care of them automatically. You will only get back what at the redirected location.

我的理解是,当服务器将 302 响应发给浏览器时,浏览器并不是直接进行 ajax 回调处理,而是先执行 302 重定向——从 Response Headers 中读取 location 信息,然后向 location 中的 url 发出请求,在收到这个请求的响应后才会进行 ajax 回调处理。

大致流程如下:

ajax -> browser -> server -> 302 -> browser(redirect) -> server -> browser -> ajax callback

所以,在 axios 的响应中并不能拦截到 302 请求,于是我继续去看了这篇 issue

There is no library that could prevent the redirect. What you need to do on your server-side is distinguish between XHR requests and normal browser navigation requests and send either a 403 w/ JSON and specify the URL you want to redirect to in there or send a 302 if the request is being made by a browser navigation request.

所以最后给出的解决方案是服务端区分 ajax 请求和浏览器请求,在 ajax 请求是返回 403 和需要重定向到的 url,在浏览器请求时直接返回 302 跳转。或者前端直接访问该接口的 url,而不要采用 ajax。

你可能感兴趣的:(ajax,遇到重定向)