Illustrations and texts teach you how to simulate the 302 interface and implement various solutions for axios and fetch to jump after encountering the 302 status code in js. Axios and fetch successfully respond to intercept 302

Recap

  • In daily work, we will use fetch, or axios to initiate requests to obtain data, but when we encounter some special needs, after using different libraries, we will get different results, such as 302, 308 status codes, so how should we deal with it? What about these two situations?

Below I will teach you how to implement it step by step:

  • How to use multiple solutions to implement front-end code + 302 back-end interface to achieve page jump?
  • How to handle 302 when fetch sends GET or POST request? Or how can fetch intercept 302?
  • What are the solutions for Axios to intercept 302 status codes in response? How to achieve?

Basic environment preparation

Start a simple nodejs backend with simple code

Initialize project
npm init
Install dependencies
npm install express cors --save

Simulate several 302 requests

Create app.js file in the root directory, we simulate some 302 requests


var express = require("express");
var app = express();
const cors = require("cors");
//跨域请求cors
app.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}成功`);
});


Precautions
  • I only tried 302 for the following status codes. You can modify the backend code to test other conditions~~

重定向状态码:
301: Moved Permanently
302: Found
303: See Other
307: Temporary Redirect
308: Permanent Redirect

Start http service
node app.js

Or use supervisor to perform hot updates of server-side code

How to use supervisor (it is recommended to use it to start the code)
  • npm official documentation
  • Node Supervisor is used to restart the program if it crashes.
  • It can also be used to restart the program when *.js files change.
npm install supervisor -g
supervisor app.js
Started successfully

Interface testing

Front-end preparation

I am using Vue as an example here~~, it is the same for other frameworks~~

Create project

npm create vue@latest

Download dependencies
cd 项目名
npm install
Startup project
npm run dev


Prepare basic page
<script setup>

</script>

<template>
  <main class="main">
    <button>测试</button>
  </main>
</template>
<style scoped>
.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;
}
</style>

Function 1: How to use front-end code + 302 back-end interface to achieve page jump?

Option 1 - window.location.assign (jump to current page)

We add the following code to the project

<script setup>
const urlInfo = {
  baidu: 'http://localhost:3002/redirect-baidu'
}
const toBaidu = () => {
  console.log(1)
  window.location.assign(urlInfo.baidu)
}
</script>

<template>
  <main class="main">
    <button @click="toBaidu">点击此处跳转百度</button>
  </main>
</template>
Option 2 - window.open (open a new page, or open the current page, you can control the parameters yourself)

The core code is as follows: (The detailed code will be pasted later)

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

The core code is as follows: (The detailed code will be pasted later)

 window.open(urlInfo.baidu, '_blank');
Function 1 overall code
<script setup>
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
}
</script>

<template>
  <main class="main">
    <button @click="toBaidu1">点击此处跳转百度-1</button>
    <button @click="toBaidu2">点击此处跳转百度-2</button>
    <button @click="toBaidu3">点击此处跳转百度-3</button>
  </main>
</template>
<style scoped>
.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;
}
</style>

Function 2: How to handle 302 when fetch sends GET or POST request? Or how can fetch intercept 302?

We use several simulated URLs to display several situations, and then based on the returned results, everyone will know how to handle the 302 situation.`

Case 1:
<script setup>
const urlInfo = {
  baidu: 'http://localhost:3002/redirect-baidu',
  error: 'http://localhost:3002/redirect-error',
  notFound: 'http://localhost:3002/redirect-not-found',
}
const currentUrl = urlInfo.baidu
const 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)
  })
}

</script>

<template>
  <main class="main">
    <button @click="fetchGet">Fetch-Get-302</button>
    <button @click="fetchPost">Fetch-Post-302</button>
  </main>
</template>
<style scoped>
.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;
}
</style>


Case 2:

Switch URL

<script setup>
const urlInfo = {
  baidu: 'http://localhost:3002/redirect-baidu',
  error: 'http://localhost:3002/redirect-error',
  notFound: 'http://localhost:3002/redirect-not-found',
}
const currentUrl = urlInfo.error
const 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)
  })
}

</script>

<template>
  <main class="main">
    <button @click="fetchGet">Fetch-Get-302</button>
    <button @click="fetchPost">Fetch-Post-302</button>
  </main>
</template>
<style scoped>
.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;
}
</style>


Let’s analyze this situation. The 302 redirect URL is the URL that returns 500. At this time, we can get the redirected result. At this time, we have a way to deal with it~

Case 3:

Switch URL

<script setup>
const urlInfo = {
  baidu: 'http://localhost:3002/redirect-baidu',
  error: 'http://localhost:3002/redirect-error',
  notFound: 'http://localhost:3002/redirect-not-found',
}
const currentUrl = urlInfo.notFound
const 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)
  })
}

</script>

<template>
  <main class="main">
    <button @click="fetchGet">Fetch-Get-302</button>
    <button @click="fetchPost">Fetch-Post-302</button>
  </main>
</template>
<style scoped>
.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;
}
</style>

Case 4:

Change the URL to 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


Summarize
  • Using Fetch, when the target URL of 302 redirection is cross-domain, we cannot obtain the specific information of the request at this time, and can only get the error result in catch.
  • When using Fetch, the target URL of 302 redirect returns status code 200, 404, 500. We can accurately know through res.redirected that the interface is a redirect at this time, and obtain the accurate redirect URL through res.url returned by the backend interface.
  • To sum up, when the redirection target URL is normal, we can use Fetch to successfully respond to intercept the 302 status code and do subsequent logical processing, because the cors situation is very easy to handle, and using other configurations such as proxies can completely avoid this. Condition.

Function 3: How to handle 302 when axios sends GET or POST request? What are the solutions for Axios to intercept 302 status codes in response? How to achieve?

Download dependencies
 npm i axios --save
Write basic code
<script setup>
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.success
const 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)
  })
}

</script>

<template>
  <main class="main">
    <button @click="axiosGet">Axios-Get-302</button>
    <button @click="axiosPost">Axios-Post-302</button>
  </main>
</template>
<style scoped>
.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;
}
</style>

Case 1:
const currentUrl = urlInfo.success

Case 2:

In the case of cross-domain, catch will be used, and then the error message of Network Error will be obtained.

{
    "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
}

Case 3:

Case 4:

in conclusion

Let’s print the unified return data

{
    "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
}
  • Using Axios, when the target URL of 302 redirection is cross-domain, we cannot obtain the specific information of the request at this time. We can only get the error result and error display information in the catch.
  • When using Axios, the target URL of 302 redirection returns status code 200, we can compare res.request.responseURL with res.config.url to accurately know whether the interface is redirected at this time, and through the backend interface The returned res.request.responseURL, and if the redirected url is an html page, we add it to determine whether the headers["content-type"] type contains text/html to get the accurate redirected URL.
  • When using Axios, the target URL of 302 redirection returns status code 404,500, we can capture error.request.responseURL in catch and compare it with error.config.url to accurately know whether the interface is redirected at this time, and through The error.request.responseURL returned by the backend interface, and if the redirected url is an html page, we add it to determine whether the headers["content-type"] type contains text/html to get the accurate redirected URL.
  • To sum up, when the redirection target URL is normal, we can use Axios to successfully respond to intercept the 302 status code and do subsequent logical processing, because the cors situation is very easy to handle, and using other configurations such as proxies can completely avoid this Condition.
Analysis diagram

code
<script setup>
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.success
const 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')
    })
}

</script>

<template>
    <main class="main">
        <button @click="axiosGet(urlInfo.success)">Axios-Get-302-success</button>
        <button @click="axiosPost(urlInfo.success)">Axios-Post-302-success</button>

        <button @click="axiosGet(urlInfo.baidu)">Axios-Get-302-baidu</button>
        <button @click="axiosPost(urlInfo.baidu)">Axios-Post-302-baidu</button>

        <button @click="axiosGet(urlInfo.error)">Axios-Get-302-error</button>
        <button @click="axiosPost(urlInfo.error)">Axios-Post-302-error</button>

        <button @click="axiosGet(urlInfo.notFound)">Axios-Get-302-notFound</button>
        <button @click="axiosPost(urlInfo.notFound)">Axios-Post-302-notFound</button>
    </main>
</template>
<style scoped>
.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;
}
</style>

code repository

That’s all for today~
  • Friends, ( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝSee you tomorrow~~
  • Everyone, please be happy every day

Everyone is welcome to point out areas that need correction in the article~
There is no end to learning and win-win cooperation

Insert image description here

Welcome the brothers and sisters passing by to give better opinions~~

Guess you like

Origin blog.csdn.net/tangdou369098655/article/details/134771029