Vue3Axios封装Axios跨域配置 创建服务器提供数据 -全面详解(学习总结---从入门到深化)

Posted 童小纯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3Axios封装Axios跨域配置 创建服务器提供数据 -全面详解(学习总结---从入门到深化)相关的知识,希望对你有一定的参考价值。

👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者
📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
🍂博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人 

目录

Axios封装

Axios跨域配置 

创建服务器提供数据 


Axios封装

封装 axios 之后,在使用上会更优雅,我们知道面向对象编程 (OOP)遵循,低耦合高内聚。我们把网络请求放在一起更利于后期维护 

import axios from "axios"
import qs from "querystring"
/**
 * 处理错误信息
 * status:状态吗
 * info:具体信息
 */
const errorHandle = (status,info) =>
    switch(status)
        case 400:
            console.log("语义错误");
            break;
        case 401:
            console.log("服务器认证失败");
            break;
        case 403:
            console.log("服务器请求拒绝执行");
            break;
        case 404:
            console.log("请检查网路请求地址");
         break;
        case 500:
            console.log("服务器发生意外");
            break;
        case 502:
            console.log("服务器无响应");
            break;
        default:
            console.log(info);
            break;
   

/**
 * 创建Axios对象
 */
const instance = axios.create(
    baseURL:"http://iwenwiki.com",
    timeout:5000
)
/**
 * 拦截器
 */
instance.interceptors.request.use(
    config =>
        if(config.method === 'post')
            config.data = qs.stringify(config.data)
       
        return config
   ,
    error => Promise.reject(error)
)

instance.interceptors.response.use(
    response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response),
    error =>
        const  response  = error;
        if(response)
           errorHandle(response.status,response.info)
       else
            console.log("网络请求被中断了");
       
   
)
export default instance
import axios from "../utils/request"
const baseUrl = 
  banner:"/api/blueberrypai/getIndexBanner.php"

const api = 
    getBanner()
        return axios.get(baseUrl.banner)
   

export default api
<template>
    <h3>网络请求</h3>
    <ul>
      <li v-for="item in fingerUnion.data" :key="item">
            <h3> item.title </h3>
            <p> item.content </p>
        </li>
    </ul>
</template>
<script setup>
  import  onMounted,reactive  from "vue"
  import api from "../../api"
  const fingerUnion = reactive(
      data:
)
onMounted(() =>
    api.getBanner().then(res =>
        fingerUnion.data = res.data.banner
   )
)
</script>

实时效果反馈

1.下列代码,画横线处应该填写的代码是:

import axios from "axios"
import qs from "querystring"
/**
 * 处理错误信息
 * status:状态吗
 * info:具体信息
 */
const errorHandle = (status,info) =>
   switch(status)
        case 400:
            console.log("语义错误");
            break;
        case 401:
            console.log("服务器认证失败");
            break;
        case 403:
            console.log("服务器请求拒绝执行");
            break;
        case 404:
            console.log("请检查网路请求地址");
            break;
        case 500:
            console.log("服务器发生意外");
            break;
        case 502:
            console.log("服务器无响应");
            break;
        default:
            console.log(info);
            break;
   

/**
 * 创建Axios对象
 */
const instance = axios.create(
    baseURL:"http://iwenwiki.com",
    timeout:5000
)
/**
* 拦截器
 */
instance.___.request.use(
    config =>
        if(config.method === 'post')
            config.data = qs.stringify(config.data)
       
        return config
   ,
    error => Promise.reject(error)
)
instance.___.response.use(
    response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response),
    error =>
        const  response  = error;
        if(response)
           errorHandle(response.status,response.info)
       else
            console.log("网络请求被中断了");
       
   
)
export default instance

A axios

B response

C instance

D interceptors

Axios跨域配置 

在工作的真实场景中,跨域是常见问题,所以我们需要解决跨域问题 

import  fileURLToPath, URL  from 'node:url'
import  defineConfig  from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig(
  plugins: [vue()],
   resolve: 
    alias: 
      '@': fileURLToPath(new URL('./src', import.meta.url))
   
 ,
  server: 
    proxy: 
      '^/api': 
        target: 'http://iwenwiki.com', // 后端服务实际地址
        changeOrigin: true, //开启代理
        rewrite: (path) => path.replace(/^\\/api/, '')
     
   
 
)
<template>
    <h3>网络请求</h3>
    <ul>
        <li v-for="item in list.info" :key="item.id">
            <p> item.title </p>
        </li>
    </ul>
</template>
<script setup>
  import  onMounted,reactive  from "vue"
  import axios from "axios"
  const list = reactive(
     info:[]
)
onMounted(() =>
   axios.get("/api/api/FingerUnion/list.php")
   .then(res =>
        list.info = res.data.data
   )
   .catch(error =>
        console.log(error);
   )
)
</script>

实时效果反馈

1.下列代码,画横线处应该填写的代码是:

import  fileURLToPath, URL  from 'node:url'
import  defineConfig  from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig(
  plugins: [vue()],
  resolve: 
    alias: 
      '@': fileURLToPath(new URL('./src', import.meta.url))
   
 ,
  server: 
    proxy: 
      '^/api': 
        ___: 'http://iwenwiki.com', // 后端服务实际地址
        changeOrigin: true, //开启代理
        rewrite: (path) => path.replace(/^\\/api/, '')
     
   
 
)

A axios

B target

C instance

D interceptors

创建服务器提供数据 

在真实开发场景中,很多项目是前后端同时开发,那么前端就不会第一时间拿到接口数据,但是为了前端开发期间的测试,我们还是 需要自己创建服务器的 

const express = require("express");
const app = express();
const router = require("./router");
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded(
    extended:true
))
app.use("/api",router);
app.listen(3000,() =>
    console.log("server running at port 3000");
)
const express = require("express");
const router = express.Router();
const url = require("url");
const list = require("./data/list")
router.get("/list",(req,res) =>
    const page = url.parse(req.url,true).query.page;
    res.send(
        status:200,
        result:list,
        page
   )
)
router.post("/login",(req,res) =>
    const username = req.body.username;
    const password = req.body.password;
    res.send(
        status:200,
        username,
        password
   )
)
module.exports = router;
module.exports = [
   
        id:1001,
        name:"衣服"
   ,
   
        id:1002,
        name:"鞋子"
  ,
   
        id:1003,
        name:"电脑"
   
]

Servlet与vue-axios交互跨域问题之Access-Control-Allow-Origin' header contains multiple values '*, nul

问题简述:

  使用servlet与vue-axios进行前后端交互时,设置好了跨域,其后因考虑到用户验证问题,在前端请求时加入了请求头如下

axios.defaults.headers.common[‘token‘] = sessionStorage.getItem("token");

  其后,浏览器便报出了如下的错误

Access to XMLHttpRequest at ‘http://127.0.0.1:8081/test‘ from origin ‘null‘ has been blocked by CORS policy: 
The ‘Access-Control-Allow-Origin‘ header contains multiple values ‘*, null‘, but only one is allowed.

  但是如果去掉添加的token则可以顺利通过,虽然报错的意思比较明显,但是依旧不明白怎么会有多个值呢?加上网上大多博主的意思也是设置了2次跨域,但是只有一个是允许的,可博主们用了比较厉害的Nginx代理,而我这初学者只用了servlet,顶天了加了一个过滤器(Filter)(曾一度窃喜怎么会有这么厉害的过滤器......),所以应该不存在博主们说的Nginx代理使得过滤器重复的问题。

解决办法:

  百思不得其解之下,突然想起好像servlet可以在web.xml中进行跨域设置,检查了项目下的web.xml,果然在进行过滤器配置的时候,无脑修改了web.xml,如下:

<!--映射过滤器 -->
	<filter-mapping>
		<filter-name>FilterControl</filter-name>
		<!--“/*”表示拦截所有的请求 -->
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<filter-name>CORS</filter-name>
		<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CORS</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

  注释掉了下面代码:

<!-- <filter>
		<filter-name>CORS</filter-name>
		<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CORS</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
 -->

  问题得以解决.......

设置了两次跨域允许,同时在前端传入了token。

以上是关于Vue3Axios封装Axios跨域配置 创建服务器提供数据 -全面详解(学习总结---从入门到深化)的主要内容,如果未能解决你的问题,请参考以下文章

vueCli3 封装axios 及 配置proxy跨域

Vue--封装axios跨域

vue3 + typescript + axios封装(附带loading效果,...并携带跨域处理,...element-plus按需引入)

解决react项目中跨域和axios封装使用

VueAxios详解

axios二次封装(详细+跨域问题)