그림과 텍스트는 302 인터페이스를 시뮬레이션하고 axios 및 fetch에 대한 다양한 솔루션을 구현하여 js에서 302 상태 코드를 만난 후 점프하는 방법을 알려줍니다. Axios 및 fetch는 가로채기 302에 성공적으로 응답합니다.

요약

  • 일상 업무에서는 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>

코드 저장소

오늘은 여기까지입니다~
  • 친구들아, ( ̄Ω ̄( ̄Ω ̄〃 ( ̄Ω ̄〃))ゝ내일 만나요~~
  • 여러분 매일매일 행복하세요

기사에서 수정이 필요한 부분을 지적해주시면 누구든지 환영합니다~
배움과 상생협력에는 끝이 없습니다

여기에 이미지 설명을 삽입하세요.

지나가는 형제자매님들 환영합니다~~ 더 좋은 의견 부탁드립니다~~

추천

출처blog.csdn.net/tangdou369098655/article/details/134771029