zoukankan      html  css  js  c++  java
  • Vue学习笔记(十二) Vue Ajax

    1、简介

    在 Vue.js 中我们可以使用 Axios 完成 Ajax 请求,Axios 是一个基于 Promise 的 HTTP 库

    这篇文章的文字不多,基本都是代码,解释也都写在注释里面啦

    有兴趣的朋友也可以直接去看看官方文档:http://www.axios-js.com/zh-cn/docs/

    2、安装

    (1)CDN

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    

    (2)NPM

    > npm install axios
    

    3、GET 请求

    <!DOCTYPE html>
    <html>
    
    <head>
        <title>Demo</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/axios/dist/axios.js"></script>
    </head>
    
    <body>
        <div id="app">
            <p>{{ info }}</p>
        </div>
    
        <script>
            new Vue({
                el: '#app',
                data: {
                    info: null
                },
                mounted: function () {
                    let _this = this;
                    // GET 方法原型: axios.get(url[, config])
                    // 可以在 URL 中添加参数
                    axios
                        .get('http://www.httpbin.org/get?firstName=Steve&lastName=Jobs') 
                        .then(function (response) { _this.info = response.data; })
                        .catch(function (error) { console.log(error); });
                }
            })
        </script>
    </body>
    
    </html>
    

    4、响应结构

    当我们发送请求后,接收到的响应(response)究竟是个什么东西呢?下面让我们来看一看

    {
        // 服务器返回的数据
    	// http://www.httpbin.org 是一个用于测试请求的网站,它所返回的数据就是我们请求的信息
        data: {},
    
        // 状态码
        status: 200,
    
        // 状态码对应的状态信息
        statusText: "OK",
    
        // 响应头
        headers: {},
    
        // 为请求提供的配置信息
        config: {}
    }
    

    5、POST 请求

    <!DOCTYPE html>
    <html>
    
    <head>
        <title>Demo</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/axios/dist/axios.js"></script>
    </head>
    
    <body>
        <div id="app">
            <p>{{ info }}</p>
        </div>
    
        <script>
            new Vue({
                el: '#app',
                data: {
                    info: null
                },
                mounted: function () {
                    let _this = this;
                    // POST 方法原型: axios.post(url[, data[, config]])
                    // 可以通过 data 添加参数
                    axios
                        .post('http://www.httpbin.org/post', {
                            firstName: 'Steve',
                            lastName: 'Jobs'
                        })
                        .then(function (response) { _this.info = response.data; })
                        .catch(function (error) { console.log(error); });
                }
            })
        </script>
    </body>
    
    </html>
    

    5、请求配置

    除了上面两种常见的用法,我们还可以给 axios() 方法传入一个配置对象,里面包含用于请求的相关配置

    比如说,我们可以用这种方法发送一个简单的 GET 请求:

    axios({
        url: 'http://www.httpbin.org/get',
        method: 'get',
        params: {
            firstName: 'Steve',
            lastName: 'Jobs'
        }
    })
    

    同样的,我们也可以用这种方法发送一个简单的 POST 请求:

    axios({
        url: 'http://www.httpbin.org/post',
        method: 'post',
        data: {
            firstName: 'Steve',
            lastName: 'Jobs'
        }
    })
    

    此外,一些比较常用的配置项如下:

    • url:请求 URL,唯一的必填项
    • baseURL:自动加在 url 前,以便于 url 使用相对路径
    • method:请求方法,默认为 get
    • headers:请求头
    • params:请求参数
    • paramsSerializer:将 params 序列化
    • data:请求数据
    • transformRequest:在发送请求前允许修改请求数据
    • transformResponse:在接收响应前允许修改响应数据
    • timeout:指定超时时间
    • withCredentials:表示跨域请求时是否需要使用凭证,默认为 false
    • auth:表示使用 HTTP 基础验证并提供凭据
    • responseType:服务器响应的数据类型,默认为 json
    • maxContentLength:服务器响应内容的最大长度

    我们还可以为请求配置设置默认值:

    // 例如,下面设置 baseURL 为 https://www.example.com
    axios.defaults.baseURL = 'https://www.example.com'
    

    6、拦截器

    我们 then()catch() 之前拦截请求或响应,并对它们进行一些处理

    // 添加请求拦截器
    var RequestInterceptor = axios.interceptors.request.use(function (config) {
    	// 对请求数据做点什么
    	return config;
    }, function (error) {
    	// 对请求错误做点什么
    	return Promise.reject(error);
    });
    
    // 添加响应拦截器
    var ResponseInterceptor = axios.interceptors.response.use(function (response) {
    	// 对响应数据做点什么
    	return response;
    }, function (error) {
    	// 对响应错误做点什么
    	return Promise.reject(error);
    });
    

    如果想移除拦截器,也很简单

    // 移除请求拦截器
    axios.interceptors.request.eject(RequestInterceptor);
    
    // 移除响应拦截器
    axios.interceptors.response.eject(ResponseInterceptor);
    

    7、并发请求

    axios.all() 可以批量发送请求,然后等所有请求都返回结果时,才执行一个回调

    axios.all([
        asyncMethodOne(),
        asyncMethodTwo()
    ])
    .then(axios.spread(function (resOne, resTwo) {
        // 现在两个异步请求 asyncMethodOne 和 asyncMethodTwo 都已完成
        // resOne 和 resTwo 分别是两个请求返回的响应
    }))
    

    补充:最近在写 axios 的时候遇到 跨域问题,查了很久资料才最终解决,这里也写下来记录一下

    问题是这样子的,就是我要在利用 @vue/cli 搭建的项目中使用 axios 请求第三方天气查询的接口

    http://t.weather.sojson.com/api/weather/city/101280101(GET 请求,在浏览器打开可以直接看到返回结果)

    然后,按照上面的套路,很容易就能写出下面的代码:

    axios
        .get('http://t.weather.sojson.com/api/weather/city/101280101')
        .then(function(res) { console.log(res); })
        .catch(function(err) { console.log(err); })
    

    可是,当我们运行项目 npm run serve,打开浏览器控制台查看结果的时候居然报错了,出错信息如下:

    Access to XMLHttpRequest at 'http://t.weather.sojson.com/api/weather/city/101280101'

    from origin 'http://localhost:8080' has been blocked by CORS policy:

    No 'Access-Control-Allow-Origin' header is present on the requested resource.

    后来在网上查了一下才知道,由于同源策略的限制,我们是不能直接进行跨域请求的

    所谓跨域请求,是指请求 URL 与当前页面 URL 的协议、域名、端口三者任意之一不同

    那要怎么解决呢?以下就是利用 @vue/cli 搭建的项目在开发环境下使用 axios 进行跨域请求的解决方案

    1. 在项目的根目录下新建 vue.config.js 配置文件,并在文件中添加配置代码
    // vue.config.js
    module.exports = {
        // 使用后端 API 服务器发送请求,这样可以避免跨域问题
        devServer: {
            proxy: {
                // 自定义标识符,当请求以 '/sojson' 开头才使用代理
                '/sojson': {
                    // 目标主机的协议和域名
                    target: 'http://t.weather.sojson.com', 
                    ws: true,
                    changeOrigin: true,
                    // 路径重写,在发送请求时将 '^/sojson' 替换成 ''
                    pathRewrite: {
                        '^/sojson': ''
                    }
                }
            }
        }
    }
    
    1. 使用 axios 发送请求,注意请求地址的变化
    axios
        .get('/sojson/api/weather/city/101280101')
        .then(function(res) { console.log(res); })
        .catch(function(err) { console.log(err); })
    
    // 此时,请求 URL 为 '/sojson/api/weather/city/101280101'
    // 因为请求以 '/sojson' 开头,符合自定义标识符,所以使用代理
    // 因为请求以 '/sojson' 开头,符合路径重写规则,所以将其替换为 ''
    // 拼接上目标主机的协议和域名 'http://t.weather.sojson.com'
    // 最终使用代理发送的请求为 'http://t.weather.sojson.com/api/weather/city/101280101'
    
    1. 最后重新启动项目 npm run serve(重要),就可以实现跨域请求啦

    再补充:最近又遇到一个问题,就是 GET 请求没有问题,但是 POST 请求却得不到正确的数据

    比如说,我们通过 POST 请求有道翻译的接口:https://fanyi.youdao.com/translate

    和上面一样,我们还是需要先解决跨域的问题,在 vue.config.js 文件写好配置就行

    module.exports = {
        devServer: {
            proxy: {
                '/youdao': {
                    target: 'https://fanyi.youdao.com', 
                    ws: true,
                    changeOrigin: true,
                    pathRewrite: {
                        '^/youdao': ''
                    }
                }
            }
        }
    }
    

    然后,按照上面类似的写法使用 axios

    axios({
        url: '/youdao/translate',
        method: 'POST',
        data: {
              'i': 'Hello', // 翻译的内容
              'doctype': 'json',
              'from': 'AUTO',
              'to': 'AUTO'
        }
    }).then(function(res) {
        console.log(res);
    }).catch(function(err) {
        console.log(err);
    })
    

    但是当运行项目时你会发现,我们得不到正确的数据,这时候我们只需要做一点小改动就好

    import qs from 'qs'
    let fromData = {
        'i': 'Hello',
        'doctype': 'json',
        'from': 'AUTO',
        'to': 'AUTO'
    }
    axios({
        url: '/youdao/translate',
        method: 'POST',
        // 设置请求头 content-type
        headers: { 'content-type': 'application/x-www-form-urlencoded' },
        // 将对象序列化为 URL 形式
        data: qs.stringify(fromData)
    }).then(function(res) {
        console.log(res);
    }).catch(function(err) {
        console.log(err);
    })
    

    【 阅读更多 Vue 系列文章,请看 Vue学习笔记

    版权声明:本博客属于个人维护博客,未经博主允许不得转载其中文章。
  • 相关阅读:
    BZOJ 1968: [Ahoi2005]COMMON 约数研究
    BZOJ 2463: [中山市选2009]谁能赢呢?
    BZOJ 2462: [BeiJing2011]矩阵模板
    hihoCoder 后缀自动机三·重复旋律6
    hihoCoder #1445 : 后缀自动机二·重复旋律5
    BZOJ 2179: FFT快速傅立叶
    BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡
    BZOJ 2946: [Poi2000]公共串
    BZOJ 2882: 工艺
    SPOJ LCS2
  • 原文地址:https://www.cnblogs.com/wsmrzx/p/11255605.html
Copyright © 2011-2022 走看看