Axios网络请求

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

特性

  • 从浏览器创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 超时处理
  • 查询参数序列化支持嵌套项处理
  • 自动将请求体序列化为:
    • JSON (application/json)
    • Multipart / FormData (multipart/form-data)
    • URL encoded form (application/x-www-form-urlencoded)
  • 将 HTML Form 转换成 JSON 进行请求
  • 自动转换JSON数据
  • 获取浏览器和 node.js 的请求进度,并提供额外的信息(速度、剩余时间)
  • 为 node.js 设置带宽限制
  • 兼容符合规范的 FormData 和 Blob(包括 node.js)
  • 客户端支持防御XSRF

安装

使用 npm:

1
npm install axios

跨域问题

为什么会出现跨域问题?

  • 为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源,称为同源策略,同源策略是浏览器安全的基石
  • 同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能
  • 所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
  • 当一个请求url的协议、域名、端口三者之间任意一个与当前页面ur!不同即为跨域,,此时无法读取非同源网页的 Cookie,无法向非同源地址发送 AJAX 请求

怎么解决跨域问题?

  • 跨源资源共享(CrossSource Resource共享)是由W3C制定的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域请求。
  • CORS可以在不破坏即有规则的情况下,通过后端服务器实现CORS接口,从而实现跨域通信。
  • 科拉斯将请求分为两类:简单请求非简单请求,分别对跨域通信提供了支持。

简单请求

满足以下条件的请求即为简单请求:

  • 请求方法:GET、POST、HEAD
  • 除了以下的请求头字段之外,没有自定义的请求头:
    Accept、Accept-Language、Content-Language、Last-Event-lD.Content-Type
  • Content-Type的值只有以下三种:
    text/plain、multipart/form-data、 application/x-www-form-urlencoded

简单请求的服务器处理

  • 对于简单请求,CORS的策略是请求时在请求头中增加一个Origin字段

    1
    2
    3
    Host:localhost:8080
    Origin:http://localhost:8081
    Referer:http://localhost:8081/index.html
  • 服务器收到请求后,根据该字段判断是否允许该请求访问,如果允许,则在HTTP头信息中添加Access-Control-Alow-Origin字段。

    1
    2
    3
    4
    Access-Control-Allow-0rigin:http://localhost:8081
    Content-Length:20
    Content-Type:text/plain;charset=UTF-8
    Date:Thu,12 Jul2018 12:51:14 GMT

非简单请求

  • 对于非简单请求的跨源请求,浏览器会在真实请求发出前增加一次OPTION请求,称为预检请求(preflight request)

  • 预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到HTTP头信息字段中,询问服务器是否允许这样的操作。

  • 例如一个GET请求:

    1
    2
    3
    4
    5
    OPTIONS /test HTTP/1.1
    Origin:http://www.test.com
    Access-Control-Request-Method:GET
    Access-Control-Request-Headers:X-Custom-Header
    Host:www.test.com
  • Access-Control-Request-Method表示请求使用的HTTP方法,Access-Control-Request-Headers包含请求的自定义头字段

在Spring Boot中配置CORS

后端可加个@CrossOrigin注解对单个Controller进行放行

在传统的Java EE开发中,可以通过过滤器统一配置,而Spring Boot中对此则提供了更加简洁的解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class CorsConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 允许跨域访问的路径
.allowedOrigins("*") // 允许跨域访问的源
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许请求方法
.maxAge(168000) // 预检间隔时间
.allowedHeaders("*") // 允许头部设置
.allowCredentials(true); // 是否发送cookie
}
}

前端接受后端请求

在前端代码中,有众多功能需要访问后端代码,若对每个代码都进行单独设置会十分繁琐
所以可以通过axios进行整合

与Vue整合

  • 在实际项目开发中,几乎每个组件中都会用到 axios发起数据请求。此时会遇到如下两个问题:

  • 每个组件中都需要导入 axios

  • 每次发请求都需要填写完整的请求路径

  • 可以通过全局配置的方式解决上述问题:

    1
    2
    3
    4
    5
    6
    7
    8
    //配置请求根路径
    axios .defaults.baseURL = 'http://api.com

    //将axios作为全局的自定义属性,每个组件可以在内部直接访问(Vue3)
    app.config.globalProperties.$http=axios

    //将axios作为全局的自定义属性,每个组件可以在内部直接访问(Vue2)
    Vue.prototype.$http=axios

Axios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios'

axios.defaults.baseURL = "http://localhost:9091"//这是示例,需要根据自己端口号进行更改
Vue.prototype.$http = axios;
Vue.config.productionTip = false
Vue.use(ElementUI);

new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
1
2
3
4
this.$http.get('/brands')//用$http代替
.then(response => {
this.tableData = response.data;
})