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