요약
- 일상 업무에서는 fetch 또는 axios를 사용하여 데이터 획득 요청을 시작하지만 특별한 요구 사항이 발생할 때 다른 라이브러리를 사용한 후 302, 308 상태 코드와 같은 다른 결과를 얻게 되므로 어떻게 처리해야 합니까? 이 두 가지 상황은 어떻습니까?
아래에서는 단계별로 구현하는 방법을 알려드리겠습니다.
- 여러 솔루션을 사용하여 프런트엔드 코드 + 302 백엔드 인터페이스를 구현하여 페이지 점프를 달성하는 방법은 무엇입니까?
- 가져오기가 GET 또는 POST 요청을 보낼 때 302를 처리하는 방법은 무엇입니까? 아니면 인터셉트 302를 어떻게 가져올 수 있나요?
- 이에 대한 응답으로 302 상태 코드를 가로채는 Axios의 솔루션은 무엇입니까? 달성하는 방법?
기본 환경 준비
간단한 코드로 간단한 nodejs 백엔드 시작하기
프로젝트 초기화
npm init
종속성 설치
npm install express cors --save
여러 302 요청 시뮬레이션
루트 디렉터리에 app.js 파일을 생성하고 약 302개의 요청을 시뮬레이션합니다.
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}成功`);
});
지침
- 아래 상태코드에 대해서는 302만 시도했는데, 백엔드 코드를 수정하여 다른 조건을 테스트해볼 수 있습니다~~
중정向状态码:
301: 영구적으로 이동됨
302: 발견됨
303: 기타 보기 308: 영구 리디렉션
307: 임시 리디렉션
http 서비스 시작
node app.js
또는 감독자를 사용하여 서버 측 코드의 핫 업데이트를 수행합니다.
감독자 사용 방법(코드를 시작할 때 사용하는 것이 좋습니다)
- npm 공식 문서
- Node Supervisor는 프로그램이 충돌하는 경우 프로그램을 다시 시작하는 데 사용됩니다.
- *.js 파일이 변경되면 프로그램을 다시 시작하는 데에도 사용할 수 있습니다.
npm install supervisor -g
supervisor app.js
성공적으로 시작되었습니다
인터페이스 테스트
프론트엔드 준비
여기서는 Vue를 예로 들어보겠습니다~~다른 프레임워크도 마찬가지입니다~~
프로젝트 생성
npm create vue@latest
종속성 다운로드
cd 项目名
npm install
스타트업 프로젝트
npm run dev
기본페이지 준비
<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>
기능 1: 프런트 엔드 코드 + 302 백 엔드 인터페이스를 사용하여 페이지 점프를 달성하는 방법은 무엇입니까?
옵션 1 - window.location.sign(현재 페이지로 이동)
프로젝트에 다음 코드를 추가합니다.
<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>
옵션 2 - window.open(새 페이지를 열거나 현재 페이지를 열거나 매개변수를 직접 제어할 수 있음)
핵심 코드는 다음과 같습니다. (자세한 코드는 나중에 붙여넣을 예정입니다.)
window.open(urlInfo.baidu, '_blank');
옵션 3 - window.location.href
핵심 코드는 다음과 같습니다. (자세한 코드는 나중에 붙여넣을 예정입니다.)
window.open(urlInfo.baidu, '_blank');
기능 1 전체 코드
<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>
기능 2: 가져오기가 GET 또는 POST 요청을 보낼 때 302를 처리하는 방법은 무엇입니까? 아니면 인터셉트 302를 어떻게 가져올 수 있나요?
우리는 여러 가지 시뮬레이션된 URL을 사용하여 여러 상황을 표시한 다음 반환된 결과를 기반으로 모든 사람이 302 상황을 처리하는 방법을 알게 됩니다.
사례 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>
사례 2:
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>
이 상황을 분석해 보겠습니다. 302 리디렉션 URL은 500을 반환하는 URL입니다. 이때 리디렉션된 결과를 얻을 수 있습니다. 이때 대처 방법이 있습니다~
사례 3:
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>
사례 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를 어떻게 처리합니까? 이에 대한 응답으로 302 상태 코드를 가로채는 Axios의 솔루션은 무엇입니까? 달성하는 방법?
종속성 다운로드
npm i axios --save
기본 코드 작성
<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>
사례 1:
const currentUrl = urlInfo.success
사례 2:
Cross-domain의 경우 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 페이지인 경우 정확한 리디렉션 URL을 얻기 위해 headers["content-type"] 유형에 text/html이 포함되어 있는지 확인하기 위해 이를 추가합니다.
- Axios를 사용하면 302 리디렉션의 대상 URL이 상태 코드 404,500을 반환하므로 error.request.responseURL을 catch에 캡처하고 이를 error.config.url과 비교하면 이때 인터페이스가 리디렉션되는지 정확하게 알 수 있으며 오류를 통해 .request.responseURL은 백엔드 인터페이스에서 반환되며, 리디렉션된 URL이 html 페이지인 경우 정확한 리디렉션 URL을 얻기 위해 headers["content-type"] 유형에 text/html이 포함되어 있는지 확인하기 위해 이를 추가합니다.
- 요약하면 리디렉션 대상 URL이 정상일 때 Axios를 사용하여 302 상태 코드를 가로채고 후속 논리적 처리를 성공적으로 응답할 수 있습니다. 왜냐하면 cors 상황은 처리하기가 매우 쉽고 프록시와 같은 다른 구성을 사용하면 완전히 가능하기 때문입니다. 이 조건을 피하십시오.
분석 다이어그램
암호
<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>
코드 저장소
오늘은 여기까지입니다~
- 친구들아, ( ̄Ω ̄( ̄Ω ̄〃 ( ̄Ω ̄〃))ゝ내일 만나요~~
- 여러분 매일매일 행복하세요
기사에서 수정이 필요한 부분을 지적해주시면 누구든지 환영합니다~
배움과 상생협력에는 끝이 없습니다