原生AJAX调用遇302状态码不跳转问题求助
原生JS AJAX PUT请求不跟随重定向的解决方案
嘿,我太懂你这种搜遍全网全是jQuery方案、还被jQuery的PUT坑过的憋屈感了!原生XMLHttpRequest的重定向逻辑确实和大家常说的“自动跟随”有出入,尤其是针对PUT这类非GET/HEAD的请求,下面给你捋清楚原因和解决办法:
为什么你的PUT请求没自动跟随重定向?
根据XMLHttpRequest的规范:
- 对于GET/HEAD请求,浏览器会自动跟随301/302重定向(并保持方法不变)
- 对于POST/PUT/PATCH等请求,如果后端返回的是301/302,浏览器不会自动跟随(因为默认会把请求方法改成GET,这大概率不是你想要的)
- 只有当后端返回307/308状态码时,浏览器才会自动保留原请求方法(比如PUT)并跟随重定向
很多后端习惯返回301/302,这就是你遇到问题的根源。
手动处理重定向的原生JS方案
我们可以监听XHR的状态变化,手动检查重定向状态码,然后重新发送相同方法的请求:
function sendPutRequest(url, payload) { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === XMLHttpRequest.DONE) { // 定义需要处理的重定向状态码 const redirectCodes = [301, 302, 307, 308]; if (redirectCodes.includes(xhr.status)) { const redirectUrl = xhr.getResponseHeader('Location'); if (redirectUrl) { // 递归发送相同的PUT请求,携带原数据和请求头 sendPutRequest(redirectUrl, payload); return; } } // 处理正常响应逻辑 if (xhr.status >= 200 && xhr.status < 300) { console.log('请求成功:', xhr.responseText); // 这里可以添加你的成功回调 } else { console.error('请求失败:', xhr.status, xhr.statusText); // 这里添加错误回调 } } }; xhr.open('PUT', url); // 根据你的实际内容类型设置请求头,比如表单数据就用application/x-www-form-urlencoded xhr.setRequestHeader('Content-Type', 'application/json'); // 发送数据:如果是表单数据,直接传入FormData对象即可 xhr.send(JSON.stringify(payload)); } // 使用示例:替换成你的接口地址和数据 const yourData = { id: 123, name: 'Updated Name' }; sendPutRequest('/api/resource', yourData);
额外注意事项
- 同域限制:重定向后的URL必须和原请求同域,否则会触发CORS限制(如果跨域需要后端配置CORS允许)
- 后端优化方案:如果能说服后端把PUT请求的重定向状态码改成307/308,原生XHR会自动跟随,不需要手动处理,这是最省心的方式
- 请求头携带:如果你的请求有自定义头(比如Authorization),记得在重新发送时也要设置,上面的示例已经保留了核心的Content-Type,其他头可以按需添加
完全理解你规避jQuery的决定,原生XHR虽然代码量多一点,但可控性强,不会踩那些奇怪的框架坑~
内容的提问来源于stack exchange,提问作者Old Man Walter
相关产品推荐
相关产品推荐

