第三部分 网络请求-axios

目录

1. Ajax请求

1.1 原生ajax

1.2 jqueryAjax

1.3 fetch

1.4 axios

1.5 几种ajax库的对比

2 调用Restfull接口

2.1 restfull接口规范

2.2 qs.js库

qs.stringify() 和JSON.stringify()

qs.parse()和JSON.parse()

2.3 发送Get请求

2.4 发送post请求

1、Content-Type: application/json

2、Content-Type: multipart/form-data

3、Content-Type: application/x-www-form-urlencoded

2.5 发送put请求

2.6 发送delete请求

方式一:Content-Type: application/json

方式二:使用 parmas 属性

2.7 执行多个并发请求

3 配置axois

3.1 自定义配置

3.2 配置拦截器

4 vue中使用axios

5 axios跨域

5.1 什么时跨域问题

5.2 Vue 开发环境中配置代理

5.3 服务器端支持跨域

5.3.1 在Nodejs项目中express框架下开启支持跨域

5.3.2 在Java项目中springboot框架下开启支持跨域

 


1. Ajax请求

 

1.1 原生ajax

    //创建异步对象  
    var xhr = new XMLHttpRequest();
    //设置请求基本信息,并加上请求头
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xhr.open('post', 'test.php' );
    //发送请求
    xhr.send('name=Lan&age=18');
    xhr.onreadystatechange = function () {
        // 这步为判断服务器是否正确响应
      if (xhr.readyState == 4 && xhr.status == 200) {
        console.log(xhr.responseText);
      } 
    };

1.2 jqueryAjax

var loginBtn =  document.getElementsByTagName("button")[0];
loginBtn.onclick = function(){
    ajax({
        type:"post",
        url:"test.php",
        data:"name=lan&pwd=123456",
        success:function(data){
           console.log(data);
        }
    });
}

 

 

 

1.3 fetch

fetch('http://www.mozotech.cn/bangbang/index/user/login', {
    method: 'post',
    headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams([
        ["username", "Lan"],["password", "123456"]
    ]).toString()
})
.then(res => {
    console.log(res);
    return res.text();
})
.then(data => {
    console.log(data);
})

1.4 axios

axios({
    method: 'post',
    url: '/abc/login',
    data: {
        userName: 'Lan',
        password: '123'
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

 

1.5 几种ajax库的对比

ajax:

【优点:局部更新;原生支持】

【缺点:可能破坏浏览器后退功能;嵌套回调】

jqueryAjax:

【在原生的ajax的基础上进行了封装;支持jsonp】

fetch:

【优点:解决回调地狱】

【缺点:API 偏底层,需要封装;默认不带Cookie,需要手动添加; 浏览器支持情况不是很友好,需要第三方的ployfill】

axios:

【几乎完美】

axios的特点

  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 能转换请求和响应数据
  • 能取消请求
  • 自动转换JSON数据
  • 浏览器端支持防止CSRF(跨站请求伪造)

 

2 调用Restfull接口

2.1 restfull接口规范

URI

URI 表示资源,资源一般对应服务器端领域模型中的实体类。

URI规范:

  • 不用大写;
  • 用中杠-不用下杠_;
  • 参数列表要encode;
  • URI中的名词表示资源集合,使用复数形式。

 

服务器端的组合实体必须在uri中通过父实体的id导航访问:

组合实体不是first-class的实体,它的生命周期完全依赖父实体,无法独立存在,在实现上通常是对数据库表中某些列的抽象,不直接对应表,也无id。一个常见的例子是 User — Address,Address是对User表中zipCode/country/city三个字段的简单抽象,无法独立于User存在。必须通过User索引到Address:GET /user/1/addresses

 

HTT请求方法

通过标准HTTP方法对资源CRUD:

GET:查询

GET /zoos
GET /zoos/1
GET /zoos/1/employees

 

 

 

POST:创建单个资源。POST一般向“资源集合”型uri发起

POST /animals  //新增动物
POST /zoos/1/employees //为id为1的动物园雇佣员工

 

PUT:更新单个资源(全量),客户端提供完整的更新后的资源。与之对应的是 PATCH,PATCH 负责部分更新,客户端提供要更新的那些字段。PUT/PATCH一般向“单个资源”型uri发起

PUT /animals/1
PUT /zoos/1

 

DELETE:删除

DELETE /zoos/1/employees/2
DELETE /zoos/1/employees/2;4;5
DELETE /zoos/1/animals  //删除id为1的动物园内的所有动物

 

安全性和幂等性

  • 安全性:不会改变资源状态,可以理解为只读的;
  • 幂等性:执行1次和执行N次,对资源状态改变的效果是等价的

安全性和幂等性均不保证反复请求能拿到相同的response。以 DELETE 为例,第一次DELETE返回200表示删除成功,第二次返回404提示资源不存在,这是允许的。

复杂查询

查询可以捎带以下参数

 

 

1. 为了演示提供好以下接口:

 

 

 

2. 在页面导入以下js库

<script src="./node_modules/axios/dist/axios.js"></script>
<script src="./node_modules/qs/dist/qs.js"></script>

 

2.2 qs.js库

 

qs.stringify() 和JSON.stringify()

let a = {name:'hehe',age:10};

qs.stringify序列化结果如下:

 

name=hehe&age=10

而JSON.stringify序列化结果如下:

"{"a":"hehe","age":10}"

qs.parse()和JSON.parse()

qs.parse()将URL解析成对象的形式

let url = 'method=query_sql_dataset_data&projectId=85&appToken=7d22e38e-5717-11e7-907b-a6006ad3dba0';
 qs.parse(url);

 

解析后的结果如下:

{method: "query_sql_dataset_data", projectId: "85", appToken: "7d22e38e-5717-11e7-907b-a6006ad3dba0"}

JSON.parse()用于从一个字符串中解析出json 对象

let str = '[{"field":"thedate","v1":"20170102"},{"field":"rev_type","v1":"大数据收入"}]'
JSON.parse(str)

解析后的结果如下:

[
   {field: "thedate", v1: "20170102"},
   {field: "rev_type", v1: "大数据收入"}
]

2.3 发送Get请求

<head>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script src="./node_modules/axios/dist/axios.js"></script>
    <script src="./node_modules/qs/dist/qs.js"></script>
</head>
<body>
    <div id="app">
        <p>
            <button @click="addUser">添加</button>
            <button @click="updateUser">修改</button>
            <button @click="deleteUser">删除</button>
        </p>
        <table border="1" cellspacing="0">
            <tr>
                <th>姓名</th><th>生日</th><th>年龄</th><th>邮箱</th>
            </tr>
            <tr v-for="(user, index) in userList">
                <td>{{user.username}}</td><td>{{user.birthday}}</td><td>{{user.age}}</td><td>{{user.email}}</td>
            </tr>
        </table>

    </div>

</body>
<script>
    new Vue({
        el: '#app',
        data: {
            userList:[]
        },
        methods: {
        },  
        created() {
            // 发送get请求
            const _this = this
            axios.get('http://127.0.0.1:8080/user/1')
            .then(function(resp){
                _this.userList.push(resp.data)
            })
            .catch(function(e){
                console.error('请求失败:',e)
            })
        },
    })
</script>

 

传递GET请求参数:

• 直接在 URL 中附加参数

            getUser(){
                // 发送get请求
                const _this = this
                axios.get('http://127.0.0.1:8080/user?name=admin' )
                    .then(function(resp){
                        _this.userList.push(resp.data)
                    })
                    .catch(function(e){
                        console.error('请求失败:',e)
                    })
            }

• 使用 parmas 属性添加GET参数

            getUser(){
                // 发送get请求
                const _this = this
                axios.get('http://127.0.0.1:8080/user', {
                    params: {name: 'admin'}
                } )
                    .then(function(resp){
                        _this.userList.push(resp.data)
                    })
                    .catch(function(e){
                        console.error('请求失败:',e)
                    })
            }

2.4 发送post请求

axios POST提交数据的三种请求方式写法

1、Content-Type: application/json

 

            addUser(){
                var userData = {
                    id: 1,
                    username: 'tom',
                    birthday: '2020-08-08T13:13:25.262+0000',
                    age: 18,
                    email: 'tom@sohu.com'
                }
                // 发送post请求
                axios.post('http://127.0.0.1:8080/user', userData)
                    .then(function(resp){
                        console.log(resp.data)
                    })
                    .catch(function(e){
                        console.error('请求失败:',e)
                    })
            },

2、Content-Type: multipart/form-data

FormData

  FormData 接口提供了一种表示表单数据的键值对的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。

实现了 FormData 接口的对象可以直接在for...of结构中使用

 addUser(){
    let userFormData = new FormData()
    userFormData.append('id', '1')
    userFormData.append('username', 'tom')
    userFormData.append('birthday', '2020-08-08T13:13:25.262+0000')
    userFormData.append('age', '18')
    userFormData.append('email', 'tom@sohu.com')

    // 发送post请求
    axios.post('http://127.0.0.1:8080/user', userFormData)
        .then(function(resp){
            console.log(resp.data)
        })
        .catch(function(e){
            console.error('请求失败:',e)
        })
},

 

 

 

3、Content-Type: application/x-www-form-urlencoded

URLSearchParams 

如果你想构建一个简单的GET请求,并且通过<form>的形式带有查询参数,可以将它直接传递给URLSearchParams。URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。一个实现了 URLSearchParams 的对象可以直接用在 for...of 结构中

    addUser(){
        let userParams = new URLSearchParams()
        userParams.append('id', '1')
        userParams.append('username', 'tom')
        userParams.append('birthday', '2020-08-08T13:13:25.262+0000')
        userParams.append('age', '18')
        userParams.append('email', 'tom@sohu.com')

        // 发送post请求
        axios.post('http://127.0.0.1:8080/user', userParams)
            .then(function(resp){
                console.log(resp.data)
            })
            .catch(function(e){
                console.error('请求失败:',e)
            })
    },

            addUser(){
                var userData = {
                    id: 1,
                    username: 'tom',
                    birthday: '2020-08-08T13:13:25.262+0000',
                    age: 18,
                    email: 'tom@sohu.com'
                }
                // 发送post请求
                axios.post('http://127.0.0.1:8080/user', Qs.stringify(userData))
                    .then(function(resp){
                        console.log(resp.data)
                    })
                    .catch(function(e){
                        console.error('请求失败:',e)
                    })
            },

 

2.5 发送put请求

    updateUser(){
        var userData = {
            id: 1,
            username: 'tom',
            birthday: '2020-08-08T13:13:25.262+0000',
            age: 18,
            email: 'tom@sohu.com'
        }
        // 发送put请求
        axios.put('http://localhost:8080/user/1', userData)
            .then(function(resp){
                console.log(resp.data)
            })
            .catch(function(e){
                console.error('请求失败:',e)
            })
    },

 

 

2.6 发送delete请求

方式一:Content-Type: application/json

    deleteUser(){
        // 发送delete请求:以json对象的形式带参
        axios.delete('http://localhost:8080/user', {
            data: {age: 20}
        })
            .then(function(resp){
                console.log(resp.data)
            })
            .catch(function(e){
                console.error('请求失败:',e)
            })
    },

 

 

方式二:使用 parmas 属性

 

    deleteUser(){
        // 发送delete请求:以json对象的形式带参
        axios.delete('http://localhost:8080/user', {
            params: {age: 20}
        })
            .then(function(resp){
                console.log(resp.data)
            })
            .catch(function(e){
                console.error('请求失败:',e)
            })
    },

 

2.7 执行多个并发请求

            getUser1(){
                const _this = this
                axios.get('http://127.0.0.1:8080/user/1')
            },
            getUser2(){
                const _this = this
                axios.get('http://127.0.0.1:8080/user/2')
            },
            getMultiUser(){
                axios.all([this.getUser1(), this.getUser2()])
                .then(axios.spread(function (acct, perms) {
                    // 两个请求现在都执行完成
                }));
            }

 

3 配置axois

3.1 自定义配置

使用自定义配置新建一个 axios 实例

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

 

 

3.2 配置拦截器

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    config.auth =  {                     //设置的自定义 `Authorization`头
        username: 'janedoe',
        password: 's00pers3cret'
    }
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    console.log('响应状态码' + response.status)
    console.log('响应数据:' + JSON.stringify(response.data))
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

 

4 vue中使用axios

 

1. 使用vue-cli创建vue项目

vue create crm

2. 使用vue命令安装axios

cd crm
vue add axios

 

 

这时自动已在vue应用程序中配置好axios,后续直接使用即可

 

3. 使用axios发送ajax请求

  created(){
     // 发送get请求
      const _this = this
      axios.get('http://127.0.0.1:8080/user/1')
      .then(function(resp){
          _this.userList.push(resp.data)
      })
      .catch(function(e){
          console.error('请求失败:',e)
      })
  }

 

4. 启动服务

cd crm
$ npm run serve

 

 

报错原因: 该项目安装了eslint规范,ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。在许多方面,它和 JSLint、JSHint 相似。

解决方法1:
在package.json文件内加入如下代码:

"rules": {
	"generator-star-spacing": "off",
	"no-tabs":"off",
	"no-unused-vars":"off",
	"no-console":"off",
	"no-irregular-whitespace":"off",
	"no-debugger": "off"
},

如图所示:

解决方法2:
在安装项目的时候不安装ESLint:

Use ESLint to lint your code? NO

5 axios跨域

5.1 什么时跨域问题

axios跨域问题:Ajax加载其 它服务器的API数据,可能会 遇到跨域的问题

➢跨域,是指在当前域下,要访问 其它域中的资源

 

 

 

5.2 Vue 开发环境中配置代理

在vue.config.js配置文件中,配置代理服务器

✓访问 当前指定地址时,会把请求交给代理服务器发送,避开跨域问题

✓ Vue中使用时,直接给出不含服务器域名的url即可

 

 

1. 创建vue.config.js

// vue配置项
module.exports = {
    devServer: {
        // 遇到未知请求,将会交给代理服务器处理
        proxy: 'http://127.0.0.1:8888'
    }
}

 

2. 发送ajax请求时写相对路径

  methods: {
    addUser(){
      var userData = {
          id: 1,
          username: 'tom',
          birthday: '2020-08-08T13:13:25.262+0000',
          age: 18,
          email: 'tom@sohu.com'
      }
      // 发送post请求
      this.axios.post('/user', userData)
          .then(function(resp){
              console.log(resp.data)
          })
          .catch(function(e){
              console.error('请求失败:',e)
      })
    },
  },
  created(){
     // 发送get请求
      const _this = this
      this.axios.get('/user/1')
      .then(function(resp){
          _this.userList.push(resp.data)
      })
      .catch(function(e){
          console.error('请求失败:',e)
      })
  }
}

➢可以同时设置多个跨域请求的代理

✓发送axios请求时,请求URL要使用 指定的代理前缀

✓只对开发服务器有效,生产环境中仍存在跨域问题

 

在vue.config.js进行配置

// vue配置项
module.exports = {
    devServer: {
        // 遇到未知请求,将会交给代理服务器处理
        //proxy: 'http://127.0.0.1:8888'
        proxy: {
            '/api': {
                target: 'http://127.0.0.1:8888',
                pathRewrite: {
                    '^api/': '/' // 不是'^/api': '/'
                }
            }
        }
    }
}

 

在页面发送ajax请求

  methods: {
    addUser(){
      var userData = {
          id: 1,
          username: 'tom',
          birthday: '2020-08-08T13:13:25.262+0000',
          age: 18,
          email: 'tom@sohu.com'
      }
      // 发送post请求
      this.axios.post('/api/user', userData)
          .then(function(resp){
              console.log(resp.data)
          })
          .catch(function(e){
              console.error('请求失败:',e)
      })
    },
  },
  created(){
     // 发送get请求
      const _this = this
      this.axios.get('/api/user/1')
      .then(function(resp){
          _this.userList.push(resp.data)
      })
      .catch(function(e){
          console.error('请求失败:',e)
      })
  }

5.3 服务器端支持跨域

5.3.1 在Nodejs项目中express框架下开启支持跨域

 

1. 安装 cors 跨域支持模块 yarn add cors

yarn add cors

 

npm install -S cors

2. 启用 cors 中间件

 

 

5.3.2 在Java项目中springboot框架下开启支持跨域

在配置WebMvc相关配置类中添加如下代码:

@Configuration
public class AdminWebMvcConfing implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .allowedHeaders("*")
                .maxAge(3600)
                .allowCredentials(true);
    }

}

 

 

 

 

 

 

 

 

 

©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页