Vue+Axios发送网络请求,跨域问题和配置方法

Axios网络请求

Axios

这是一个基于promise的网络请求库,作用于node.js和浏览器中

  • 在实际开发中,前端页面所需要的数据往往需要从服务器获取

  • Axios在浏览器端使用XMLHttpRequest发送网络请求,并能够自动完成JSON数据的转换

  • 安装

    npm install axios
    
  • 文档

    https://axios-http.cn
    
  • 使用

    • 在main.js或者需要的组件中导入

      import Axios from 'axios'
      

使用created:function可以在组件被创建时调用其中的方法,mounted:function函数是在组件被渲染到页面上时调用

export default {
    created:function(){
        console.log("movie")
    }
}

发送网络请求

网络请求一般在页面加载的时候发送,在访问正确服务器端口号时,通过解析json字符串来获取数据(所以后端控制器返回值需要直接返回List或者对象而不是其他格式的字符串),axios发送的数据也是json字符串

  • 发送GET请求

    //设置请求的url和携带的参数,通过回调函数function获取对应的返回参数
    axios.get('/user?id=1').then(function(response){
    	//then是在处理成功时执行的
    }).catch(function(error){
    	//catch是在处理错误时执行的
    }).then(function()){
    	//then类似于finally,总会执行
    }
    //可以使用这种方式传递参数
    axios.get('/user',{
    	params: {
    	id: 1,
    }
    }).then(function(response){
    	//then是在处理成功时执行的
    }).catch(function(error){
    	//catch是在处理错误时执行的
    }).then(function()){
    	//then类似于finally,总会执行
    }
    
  • 发送post、delete等Restful风格请求时,将get改为对应请求方式即可

  • async/await

    前两种方式默认是异步的, 而axios可以使用js的async/await使得其等待异步调用结束,相当于变成同步方法

    async function getUser() {
    	try {
    		const response = await axios.get('/user?id=1');
    	}catch(error){
    	}
    }
    

跨域问题

浏览器向后端发生请求可能会发生以下错误,实际上请求已完成,但是被浏览器的安全机制拦截了

Access to XMLHttpRequest at 'http://localhost:8081/user' from origin 'http://192.168.31.214:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
  • 为了保证浏览器的安全,一般不允许不同源的客户端脚本在无授权的情况下读写对方的资源,称为同源策略,这是浏览器安全的基石

  • 同源是指两个页面的协议、主机号和端口号都相同,有一个不同都是不同源

  • 解决方法:CORS技术

    • Cross-Origin Resource Sharing是一种跨越请求资源共享的技术标准

    • CORS可以在不破坏既有规则的情况下,通过后端服务器实现CORS接口,从而实现跨越通信

    • CORS请求分为两类:简单请求和非简单请求

      • 简单请求:请求方法是GET、POST、HEAD;除了以下请求头字段外没有自定义的请求头Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type;其中Content-Type的值只能是三种:text/plain、multipart/from-data、application/x-www-form-urlencoded
      • 其他请求都是复杂请求
    • 对于简单请求,CORS的策略是在请求时在请求头中加一个Origin字段;服务器收到请求后,需要根据该字段判断是否允许该请求访问,如果允许则在HTTP头信息中添加Access-Control-Allow-Origin字段

    • 非简单请求需要在真实请求前发送一个OPTION请求,称为预检请求(preflight request);预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息等加到HTTP头信息字段,询问服务器的许可

      • 服务器收到请求后,需要对Origin、Access-Control-Request-Method、Access-Control-Request-Headers进行验证,验证通过会在Http响应头信息中添加Access-Control-Allow-Methods(请求允许的方法)、Access-Control-Allow-Headers(请求允许的字段)、Access-Control-Allow-Credentials(是否允许用户发送和处理Cookie、Access-Control-Max-Age(预检请求的有效期,单位是秒,有效期内不需要再发预检请求)
  • SpringBoot配置CORS

    • 配置类

      @Configuration
      public class CorsConfig implements WebMvcConfigurer {
          @Override
          public void addCorsMappings(CorsRegistry registry){
              registry.addMapping("/**") //允许跨域访问的路径
                      .allowedOrigins("*") //允许访问的源
                      .allowedMethods("POST","GET","PUT","DELETE") //允许的请求方式
                      .maxAge(16800) //允许的检测间隔时间
                      .allowedHeaders("*") //允许的请求头
                      .allowCredentials(true); //允许发送cookie
          }
      }
      
    • 注解,在控制器上添加@CrossOrigin,使得该控制器的全部跨域访问被允许

渲染数据

解决跨域问题后,可以通过response获取得到的数据,再通过修改引用的数据即可实现前后端连接

<template>
    <el-table
    :data="tableData"
    style="width: 100%"
    :row-class-name="tableRowClassName">
    <!-- 在每行结束时调用tableRowClassName,自动传递两个对应的行索引参数 -->
    <!-- 将axios的response得到的数据交给data后,把prop引用的属性名改成真实的属性名即可 -->
    <el-table-column
      prop="id"
      label="编号"
      width="180">
    </el-table-column>
    <el-table-column
      prop="username"
      label="姓名"
      width="180">
    </el-table-column>
    <el-table-column
      prop="password"
      label="密码">
    </el-table-column>
  </el-table>
</template>

<script>
import Axios from 'axios'
export default {
    created:function(){
        //这是一个异步函数,在所有请求得到响应才会执行,响应通过response取得
        //使用箭头函数解决js作用域问题,function回调函数会导致response作用域和当前的vue对象不一致,而箭头函数是一致的
        Axios.get("http://localhost:8081/user").then((response)=>{
            console.log(response)
            // 把服务器获得的数据字段交给自己data中的字段
            this.tableData = response.data;
        })
    },
    methods: {
        // 隔行改变颜色
      tableRowClassName({row, rowIndex}) {
        if (rowIndex % 2 === 0) {
          return 'warning-row';
        } else if (rowIndex % 2 === 1) {
          return 'success-row';
        }
        return '';
      }
    },
    data() {
      return {
        tableData: []
      }
    }
  }
</script>
<style>
  .el-table .warning-row {
    background: oldlace;
  }
  .el-table .success-row {
    background: #f0f9eb;
  }
</style>

Vue整合

  • 解决每个组件都需要导入Axios
  • 解决每次请求都需要写完整的请求路径

在main.js中导入Axios,配置路径前缀

import axios from 'axios'
axios.defaults.baseURL= "http://localhost:8081"
Vue.prototype.$http = axios //vue2方式,给axios导入同时设置别名,以后使用时不需要再导入,且可以使用this.$http.get来使用Axios

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值