小工具知识网

当前位置: 首页 > 行业知识 > 图文并茂教你模拟302接口,实现js中axios,fetch遇到302状态码后跳转的多种方案axios,fetch成功响应拦截302

行业知识

图文并茂教你模拟302接口,实现js中axios,fetch遇到302状态码后跳转的多种方案axios,fetch成功响应拦截302

2026-11-06 03:53:43 来源:互联网转载

前情提要

  • 日常工作中,我们会使用fetch,或者axios发起请求来获取数据,但是当我们遇到一些特殊需求的时候,使用不同库之后,会得到不同的结果,例如302,308的状态码,那么我们应该怎么处理这两种情况呢?

    下面我将会手把手教你实现:

    • 如何使用多种方案实现前端代码+302后端接口实现页面跳转?
    • fetch 发送GET 或者 POST请求如何处理 302?或者是说fetch 怎么才能拦截302?
    • Axios 响应拦截 302 状态码的方案有哪些?如何实现?

      基础环境准备

      使用简单代码启动一个简单的nodejs后端

      初始化项目
      npm init
      安装依赖
      npm install express cors --save
      模拟几个302请求

      根目录下创建app.js文件,我们模拟一些302请求

      var express = require("express");var app = express();const cors = require("cors");//跨域请求corsapp.use(  cors({    origin: "*",    credentials: true,  }));// code 200 请求app.get("/success", function (req, res) {  res.send("ok");});app.post("/success", function (req, res) {  res.send("ok");});// code 500 请求app.get("/error500", function (req, res) {  res.sendStatus(500);});const urlInfo = {  baidu: "https://www.baidu.com/",  error: "http://localhost:3002/error500", // 这个接口会返回状态码500  notFound: "http://localhost:3002/notfound", // 根本就没有这个接口  success: "http://localhost:3002/success", // 200};app.get("/redirect-success", function (req, res) {  res.redirect(302, urlInfo.success);});app.post("/redirect-success", function (req, res) {  res.redirect(302, urlInfo.success);});app.get("/redirect-baidu", function (req, res) {  res.redirect(302, urlInfo.baidu);});app.post("/redirect-baidu", function (req, res) {  res.redirect(302, urlInfo.baidu);});app.get("/redirect-error", function (req, res) {  res.redirect(302, urlInfo.error);});app.post("/redirect-error", function (req, res) {  res.redirect(302, urlInfo.error);});app.get("/redirect-not-found", function (req, res) {  res.redirect(302, urlInfo.notFound);});app.post("/redirect-not-found", function (req, res) {  res.redirect(302, urlInfo.notFound);});var http = app.listen(3002, "127.0.0.1", function () {  var httpInfo = http.address();  console.log(`创建服务${httpInfo.address}:${httpInfo.port}成功`);});
      注意事项
      • 下述状态码,我只试了302,大家可以自行修改后端代码测试其他状况哦~~

        重定向状态码:

        301: Moved Permanently

        302: Found

        303: See Other

        307: Temporary Redirect

        308: Permanent Redirect

        启动http服务
        node app.js

        或者是使用supervisor来进行服务端代码热更新

        supervisor使用方式(建议使用它来启动代码)
        • npm官方文档
        • Node Supervisor用于在程序崩溃时重新启动程序。
        • 它还可以用于在*.js文件更改时重新启动程序。
          npm install supervisor -gsupervisor app.js
          启动成功
          接口测试

          前端准备

          我这里用vue来举例子啦~~,其他框架都一样哦~~

          创建项目
          npm create vue@latest
          下载依赖
          cd 项目名npm install
          启动项目
          npm run dev
          准备基础页面
                测试  .main {  display: flex;  align-items: center;  justify-items: center;  flex-wrap: wrap;  flex-direction: column;  margin-top: 20px;}button {  font-size: 16px;  display: block;  margin-bottom: 15px;  cursor: pointer;  border: none;  color: hsla(160, 100%, 37%, 1);  padding: 10px;  width: 300px;}

          功能1:如何使用前端代码+302后端接口实现页面跳转?

          方案1 - window.location.assign(当前页跳转)

          我们在项目中添加以下代码

          const urlInfo = {  baidu: 'http://localhost:3002/redirect-baidu'}const toBaidu = () => {  console.log(1)  window.location.assign(urlInfo.baidu)}      点击此处跳转百度  
          方案2 - window.open(新页面打开,或者当前页打开,可以自己控制参数)

          核心代码如下:(详细代码将会在后面全部粘贴出来)

           window.open(urlInfo.baidu, '_blank');
          方案3 - window.location.href

          核心代码如下:(详细代码将会在后面全部粘贴出来)

           window.open(urlInfo.baidu, '_blank');
          功能1总体代码
          const urlInfo = {  baidu: 'http://localhost:3002/redirect-baidu'}const toBaidu1 = () => {  window.location.assign(urlInfo.baidu)}const toBaidu2 = () => {  window.open(urlInfo.baidu, '_blank');}const toBaidu3 = () => {  window.location.href = urlInfo.baidu}      点击此处跳转百度-1    点击此处跳转百度-2    点击此处跳转百度-3  .main {  display: flex;  align-items: center;  justify-items: center;  flex-wrap: wrap;  flex-direction: column;  margin-top: 20px;}button {  font-size: 16px;  display: block;  margin-bottom: 15px;  cursor: pointer;  border: none;  color: hsla(160, 100%, 37%, 1);  padding: 10px;  width: 300px;}

          功能2:fetch 发送GET 或者 POST请求如何处理 302?或者是说fetch 怎么才能拦截302?

          我们使用模拟的几个url来进行几种情况的展示,然后根据返回结果,大家就知道如何处理302情况了哦`

          情况1:
          const urlInfo = {  baidu: 'http://localhost:3002/redirect-baidu',  error: 'http://localhost:3002/redirect-error',  notFound: 'http://localhost:3002/redirect-not-found',}const currentUrl = urlInfo.baiduconst fetchGet = () => {  fetch(currentUrl).then(_ =>{    console.log('fetch get ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('fetch get ---catch--- current url:', currentUrl)    console.log(e)  })}const fetchPost = () => {  fetch(currentUrl,{method:'post'}).then(_ =>{    console.log('fetch post ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('fetch post ---catch--- current url:', currentUrl)    console.log(e)  })}      Fetch-Get-302    Fetch-Post-302  .main {  display: flex;  align-items: center;  justify-items: center;  flex-wrap: wrap;  flex-direction: column;  margin-top: 20px;}button {  font-size: 16px;  display: block;  margin-bottom: 15px;  cursor: pointer;  border: none;  color: hsla(160, 100%, 37%, 1);  padding: 10px;  width: 300px;}
          情况2:

          切换URL

          const urlInfo = {  baidu: 'http://localhost:3002/redirect-baidu',  error: 'http://localhost:3002/redirect-error',  notFound: 'http://localhost:3002/redirect-not-found',}const currentUrl = urlInfo.errorconst fetchGet = () => {  fetch(currentUrl).then(_ =>{    console.log('fetch get ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('fetch get ---catch--- current url:', currentUrl)    console.log(e)  })}const fetchPost = () => {  fetch(currentUrl,{method:'post'}).then(_ =>{    console.log('fetch post ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('fetch post ---catch--- current url:', currentUrl)    console.log(e)  })}      Fetch-Get-302    Fetch-Post-302  .main {  display: flex;  align-items: center;  justify-items: center;  flex-wrap: wrap;  flex-direction: column;  margin-top: 20px;}button {  font-size: 16px;  display: block;  margin-bottom: 15px;  cursor: pointer;  border: none;  color: hsla(160, 100%, 37%, 1);  padding: 10px;  width: 300px;}

          我们来分析一下这种情况,302重定向的URL是返回500的url,此时我们可以得到重定向后的结果,这个时候我们就有办法处理啦~

          情况3:

          切换URL

          const urlInfo = {  baidu: 'http://localhost:3002/redirect-baidu',  error: 'http://localhost:3002/redirect-error',  notFound: 'http://localhost:3002/redirect-not-found',}const currentUrl = urlInfo.notFoundconst fetchGet = () => {  fetch(currentUrl).then(_ =>{    console.log('fetch get ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('fetch get ---catch--- current url:', currentUrl)    console.log(e)  })}const fetchPost = () => {  fetch(currentUrl,{method:'post'}).then(_ =>{    console.log('fetch post ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('fetch post ---catch--- current url:', currentUrl)    console.log(e)  })}      Fetch-Get-302    Fetch-Post-302  .main {  display: flex;  align-items: center;  justify-items: center;  flex-wrap: wrap;  flex-direction: column;  margin-top: 20px;}button {  font-size: 16px;  display: block;  margin-bottom: 15px;  cursor: pointer;  border: none;  color: hsla(160, 100%, 37%, 1);  padding: 10px;  width: 300px;}
          情况4:

          更改URL为200情况

          const urlInfo = {  baidu: 'http://localhost:3002/redirect-baidu',  error: 'http://localhost:3002/redirect-error',  notFound: 'http://localhost:3002/redirect-not-found',  success: 'http://localhost:3002/redirect-success',}const currentUrl = urlInfo.success
          总结
          • 使用Fetch,302重定向的目标URL跨域的情况下,我们无法获取此时的请求具体信息,只能在catch里拿到报错结果
          • 使用Fetch, 302重定向的目标URL返回状态码200,404,500的情况下,我们可以通过res.redirected准确得知此时接口是重定向,以及通过后端接口返回的res.url得到准确的重定向URL
          • 综上所述,重定向目标URL正常的情况下,我们使用Fetch可以成功响应拦截 302 状态码,以及做后续的逻辑处理,因为cors的情况非常容易处理,使用代理等其他配置完全可以避免此种情况。

            功能3:axios 发送GET 或者 POST请求如何处理 302?Axios 响应拦截 302 状态码的方案有哪些?如何实现?

            下载依赖
             npm i axios --save
            编写基础代码
            import axios from 'axios';const urlInfo = {  success: 'http://localhost:3002/redirect-success',  baidu: 'http://localhost:3002/redirect-baidu',  error: 'http://localhost:3002/redirect-error',  notFound: 'http://localhost:3002/redirect-not-found',}const currentUrl = urlInfo.successconst axiosGet = () => {  axios.get(currentUrl).then(_ =>{    console.log('axios get ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('axios get ---catch--- current url:', currentUrl)    console.log(e)  })}const axiosPost = () => {  axios.post(currentUrl,{method:'post'}).then(_ =>{    console.log('axios post ---then--- current url:', currentUrl)    console.log(_)  }).catch(e=>{    console.log('axios post ---catch--- current url:', currentUrl)    console.log(e)  })}      Axios-Get-302    Axios-Post-302  .main {  display: flex;  align-items: center;  justify-items: center;  flex-wrap: wrap;  flex-direction: column;  margin-top: 20px;}button {  font-size: 16px;  display: block;  margin-bottom: 15px;  cursor: pointer;  border: none;  color: hsla(160, 100%, 37%, 1);  padding: 10px;  width: 300px;}
            情况1:
            const currentUrl = urlInfo.success
            情况2:

            跨域的情况下,会走catch,然后得到Network Error的报错提示语

            {    "message": "Network Error",    "name": "AxiosError",    "stack": "AxiosError: Network Error\n    at XMLHttpRequest.handleError (http://localhost:5173/node_modules/.vite/deps/axios.js?v=e7c1b0b9:1451:14)",    "config": {        "transitional": {            "silentJSONParsing": true,            "forcedJSONParsing": true,            "clarifyTimeoutError": false        },        "adapter": [            "xhr",            "http"        ],        "transformRequest": [            null        ],        "transformResponse": [            null        ],        "timeout": 0,        "xsrfCookieName": "XSRF-TOKEN",        "xsrfHeaderName": "X-XSRF-TOKEN",        "maxContentLength": -1,        "maxBodyLength": -1,        "env": {},        "headers": {            "Accept": "application/json, text/plain, */*"        },        "method": "get",        "url": "http://localhost:3002/redirect-baidu"    },    "code": "ERR_NETWORK",    "status": null}
            情况3:
            情况4:
            结论

            我们打印一下统一的返回数据

            {    "message": "Request failed with status code 500",    "name": "AxiosError",    "stack": "AxiosError: Request failed with status code 500\n    at settle (http://localhost:5173/node_modules/.vite/deps/axios.js?v=e7c1b0b9:1204:12)\n    at XMLHttpRequest.onloadend (http://localhost:5173/node_modules/.vite/deps/axios.js?v=e7c1b0b9:1421:7)",    "config": {        "transitional": {            "silentJSONParsing": true,            "forcedJSONParsing": true,            "clarifyTimeoutError": false        },        "adapter": [            "xhr",            "http"        ],        "transformRequest": [            null        ],        "transformResponse": [            null        ],        "timeout": 0,        "xsrfCookieName": "XSRF-TOKEN",        "xsrfHeaderName": "X-XSRF-TOKEN",        "maxContentLength": -1,        "maxBodyLength": -1,        "env": {},        "headers": {            "Accept": "application/json, text/plain, */*",            "Content-Type": "application/json"        },        "method": "post",        "url": "http://localhost:3002/redirect-error",        "data": "{\"method\":\"post\"}"    },    "code": "ERR_BAD_RESPONSE",    "status": 500}
            • 使用Axios,302重定向的目标URL跨域的情况下,我们无法获取此时的请求具体信息,只能在catch里拿到报错结果,报错显示信息
            • 使用Axios, 302重定向的目标URL返回状态码200的情况下,我们可以通过res.request.responseURL与res.config.url进行比对来准确得知此时接口是否重定向,以及通过后端接口返回的res.request.responseURL,以及如果重定向的url是html页面的话,我们加上判断headers[“content-type”]类型是否包含text/html得到准确的重定向URL
            • 使用Axios, 302重定向的目标URL返回状态码404,500的情况下,我们可以通过catch 里 捕获 error.request.responseURL与error.config.url进行比对来准确得知此时接口是否重定向,以及通过后端接口返回的error.request.responseURL,以及如果重定向的url是html页面的话,我们加上判断headers[“content-type”]类型是否包含text/html得到准确的重定向URL
            • 综上所述,重定向目标URL正常的情况下,我们使用Axios可以成功响应拦截 302 状态码,以及做后续的逻辑处理,因为cors的情况非常容易处理,使用代理等其他配置完全可以避免此种情况。
              分析图示
              代码
              import axios from 'axios';const urlInfo = {    success: 'http://localhost:3002/redirect-success',    baidu: 'http://localhost:3002/redirect-baidu',    error: 'http://localhost:3002/redirect-error',    notFound: 'http://localhost:3002/redirect-not-found',}const currentUrl = urlInfo.successconst consoleLog = (_, type) => {   //  请注意下面仅限于重定向和原有url不会包含关系    if(_.request.responseURL && _.request.responseURL.indexOf(_.config.url) === -1) {        console.log(`------------------${type} --- 拦截302 ${_.config.method} 请求------------------`)        console.log('请求URL:', _.config.url)        console.log('重定向URL:', _.request.responseURL)    }    // 如果重定向的url是html页面的话,我们还可以加上判断headers["content-type"]类型是否包含text/html}const axiosGet = (url) => {    axios.get(url).then(_ => {        consoleLog(_, 'Then')    }).catch(e => {        consoleLog(e, 'Error')    })}const axiosPost = (url) => {    axios.post(url, { method: 'post' }).then(_ => {        consoleLog(_, 'Then')    }).catch(e => {        consoleLog(e, 'Error')    })}            Axios-Get-302-success        Axios-Post-302-success        Axios-Get-302-baidu        Axios-Post-302-baidu        Axios-Get-302-error        Axios-Post-302-error        Axios-Get-302-notFound        Axios-Post-302-notFound    .main {    display: flex;    align-items: center;    justify-items: center;    flex-wrap: wrap;    flex-direction: column;    margin-top: 20px;}button {    font-size: 16px;    display: block;    margin-bottom: 15px;    cursor: pointer;    border: none;    color: hsla(160, 100%, 37%, 1);    padding: 10px;    width: 300px;}

              代码仓库

              今天就写到这里啦~
              • 小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
              • 大家要天天开心哦

                欢迎大家指出文章需要改正之处~

                学无止境,合作共赢

                欢迎路过的小哥哥小姐姐们提出更好的意见哇~~

上一篇:imc怎么设置远程登录服务器?

下一篇:API 常用的序列化协议详解