精华内容
下载资源
问答
  • axios

    千次阅读 2019-11-30 15:25:21
    axios

    1 搭建RESTful接口

    json-server:https://github.com/typicode/json-server

    npm install -g json-server
    • posts:文章
    • comments:评论
    • profile:作者
    {
        "posts": [
            {
                "id": 1,
                "title": "!!!震惊...",
                "author": "张三"
            }
        ],
        "comments": [
            {
                "id": 1,
                "body": "可以的...",
                "postId": 1
            }
        ],
        "profile": {
            "name": "张三"
        }
    }
    json-server --watch db.json

    2 测试axios

    <div>
        <button onclick="testGet()">GET请求</button>
        <button onclick="testPost()">POST请求</button>
        <button onclick="testPut()">PUT请求</button>
        <button onclick="testDelete()">DELETE请求</button>
    </div>
    <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
    /**
    * GET请求: 从服务器端获取数据
    */
    function testGet() {
    let url;
    url = 'http://localhost:3000/posts'
    // url = 'http://localhost:3000/posts/1'
    // url = 'http://localhost:3000/posts?id=1'
    axios.get(url)
      .then(response => {
        console.log('/posts get', response.data)
      })
    }
    /**
    * POST请求: 向服务器端添加新数据
    */
    function testPost() {
    const url = 'http://localhost:3000/posts'
    const data = {"title": "...救不了...", "author": "李四"};
    axios.post(url, data)
      .then(({data}) => {
        console.log('/posts post', data)
      })
      .catch(err => {
        console.error(err)
      })
    }
    /**
    * PUT请求: 更新服务器端已经数据
    */
    function testPut() {
    const url = 'http://localhost:3000/posts/2'
    const data = {"title": "...救得了...", "author": "李四"}
    axios.put(url, data)
      .then(({data}) => {
        console.log('/posts put', data)
      })
    }
    /**
    * DELETE请求: 删除服务器端数据
    */
    function testDelete() {
    const url = 'http://localhost:3000/posts/2'
    axios.delete(url)
      .then(({data}) => {
        console.log('/posts delete', data)
      })
    }

    https://blog.csdn.net/TanMengyi/article/details/109599203

    展开全文
  • Axios

    万次阅读 多人点赞 2018-09-25 20:43:07
    Axios Axios概述 首先,axios是基于promise用于浏览器和node.js的http客户端   特点 支持浏览器和node.js 支持promise 能拦截请求和响应 能转换请求和响应数据 能取消请求 自动...

    Axios

    Axios概述

    首先,axios是基于promise用于浏览器和node.js的http客户端

     

    特点

    • 支持浏览器和node.js

    • 支持promise

    • 能拦截请求和响应

    • 能转换请求和响应数据

    • 能取消请求

    • 自动转换json数据

    • 浏览器端支持防止CSRF(跨站请求伪造)

     

    一、 安装

    • npm安装

    $ npm install axios
    • bower安装

    $ bower install axios
    • 通过cdn引入

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

     

    二、 例子

    1.发起一个get请求 

    <input id="get01Id" type="button" value="get01"/>
    <script>
        $("#get01Id").click(function () {
            axios.get('http://localhost:8080/user/findById?id=1')
                .then(function (value) {
                    console.log(value);
                })
                .catch(function (reason) {
                    console.log(reason);
                })
        })
    </script>

    另外一种形式:

    <input id="get02Id" type="button" value="get02"/>
    <script>
        $("#get02Id").click(function () {
            axios.get('http://localhost:8080/user/findById', {
                params: {
                    id: 1
                }
            })
                .then(function (value) {
                    console.log(value);
                })
                .catch(function (reason) {
                    console.log(reason);
                })
        })
    </script>

    2.发起一个post请求

    在官方文档上面是这样的:

       axios.post('/user', {
                firstName: 'Fred',
                lastName: 'Flintstone'
            }).then(function (res) {
                console.log(res);
            }).catch(function (err) {
                console.log(err);
        });

    但是如果这么写,会导致后端接收不到数据

    所以当我们使用post请求的时候,传递参数要这么写:

    <input id="post01Id" type="button" value="post01"/>
    <script>
        $("#post01Id").click(function () {
            var params = new URLSearchParams();
            params.append('username', 'sertyu');
            params.append('password', 'dfghjd');
            axios.post('http://localhost:8080/user/addUser1', params)
                .then(function (value) {
                    console.log(value);
                })
                .catch(function (reason) {
                    console.log(reason);
                });
        })
    </script>

    3.执行多个并发请求

    <input id="button01Id" type="button" value="点01"/>
    <script>
        function getUser1() {
            return axios.get('http://localhost:8080/user/findById?id=1');
        }
    ​
        function getUser2() {
            return axios.get('http://localhost:8080/user/findById?id=2');
        }
    ​
        $("#buttonId").click(function () {
            axios.all([getUser1(), getUser2()])
                .then(axios.spread(function (user1, user2) {
                    alert(user1.data.username);
                    alert(user2.data.username);
                }))
        })
    </script>

    另外一种形式:

    <input id="button02Id" type="button" value="点02"/>
    <script>
        $("#button02Id").click(function () {
            axios.all([
                axios.get('http://localhost:8080/user/findById?id=1'),
                axios.get('http://localhost:8080/user/findById?id=2')
            ])
                .then(axios.spread(function (user1, user2) {
                    alert(user1.data.username);
                    alert(user2.data.username);
                }))
        })
    </script>

    当所有的请求都完成后,会收到一个数组,包含着响应对象,其中的顺序和请求发送的顺序相同,可以使用axios.spread分割成多个单独的响应对象

     

    三、 axiosAPI

    (一)可以通过向axios传递相关配置来创建请求

    axios(config)

    <input id="buttonId" type="button" value="点"/>
    <script>
        $("#buttonId").click(function () {
            var params = new URLSearchParams();
            params.append('username','trewwe');
            params.append('password','wertyu');
            // 发起一个post请求
            axios({
                method:'post',
                url:'http://localhost:8080/user/addUser1',
                data:params
            });
        })
    </script>

    axios(url[,config])

    <input id="buttonId" type="button" value="点"/>
    <script>
        $("#buttonId").click(function () {
            // 发起一个get请求,(get是默认的请求方法)
            axios('http://localhost:8080/user/getWord');
        })
    </script>

    (二)请求方法别名

    axios.request(config)
    axios.get(url[, config])
    axios.delete(url[, config])
    axios.head(url[, config])
    axios.options(url[, config])
    axios.post(url[, data[, config]])
    axios.put(url[, data[, config]])
    axios.patch(url[, data[, config]])
    // 在使用别名方法时,url、method、data这些属性都不必在配置中指定

    (三)并发请求,即是帮助处理并发请求的辅助函数

    //iterable是一个可以迭代的参数如数组等
    axios.all(iterable)
    //callback要等到所有请求都完成才会执行
    axios.spread(callback)

    (四)创建实例,使用自定义配置

    1.axios.create([config])

    var instance = axios.create({
      baseURL:"http://localhost:8080/user/getWord",
      timeout:1000,
      headers: {'X-Custom-Header':'foobar'}
    });

    2.实例的方法

    以下是实例方法,注意已经定义的配置将和利用create创建的实例的配置合并

    axios#request(config)
    axios#get(url[,config])
    axios#delete(url[,config])
    axios#head(url[,config])
    axios#post(url[,data[,config]])
    axios#put(url[,data[,config]])
    axios#patch(url[,data[,config]])

     

    四、请求配置

    请求的配置选项,只有url选项是必须的,如果method选项未定义,那么它默认是以get方式发出请求

    {
        // url 是用于请求的服务器 URL
        url: '/user/getWord',
    ​
        // method 是创建请求时使用的方法
        method: 'get', // 默认是 get
    ​
        // baseURL 将自动加在 url 前面,除非 url 是一个绝对路径。
        // 它可以通过设置一个 baseURL 便于为 axios 实例的方法传递相对路径
        baseURL: 'http://localhost:8080/',
    ​
        //  transformRequest 允许在向服务器发送前,修改请求数据
        // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
        // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
        transformRequest: [function (data) {
            // 对 data 进行任意转换处理
    ​
            return data;
        }],
    ​
        //  transformResponse 在传递给 then/catch 前,允许修改响应数据
        transformResponse: [function (data) {
            // 对 data 进行任意转换处理
    ​
            return data;
        }],
    ​
        //  headers 是即将被发送的自定义请求头
        headers: {'X-Requested-With': 'XMLHttpRequest'},
    ​
        //  params 是即将与请求一起发送的 URL 参数
        // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
        params: {
            ID: 12345
        },
    ​
        //  paramsSerializer 是一个负责 params 序列化的函数
        // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
        paramsSerializer: function (params) {
            return Qs.stringify(params, {arrayFormat: 'brackets'})
        },
    ​
        //  data 是作为请求主体被发送的数据
        // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
        // 在没有设置 transformRequest 时,必须是以下类型之一:
        // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
        // - 浏览器专属:FormData, File, Blob
        // - Node 专属: Stream
        data: {
            firstName: 'yuyao'
        },
    ​
        //  timeout 指定请求超时的毫秒数(0 表示无超时时间)
        // 如果请求话费了超过 timeout 的时间,请求将被中断
        timeout: 1000,
    ​
        //  withCredentials 表示跨域请求时是否需要使用凭证
        withCredentials: false, // 默认的
    ​
        //  adapter 允许自定义处理请求,以使测试更轻松
        // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
        adapter: function (config) {
            /* ... */
        },
    ​
        //  auth 表示应该使用 HTTP 基础验证,并提供凭据
        // 这将设置一个 Authorization 头,覆写掉现有的任意使用 headers 设置的自定义 Authorization 头
        auth: {
            username: 'zhangsan',
            password: '12345'
        },
    ​
        //  responseType 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
        responseType: 'json', // 默认的
    ​
        // xsrfCookieName 是用作 xsrf token 的值的cookie的名称
        xsrfCookieName: 'XSRF-TOKEN', // default
    ​
        //  xsrfHeaderName 是承载 xsrf token 的值的 HTTP 头的名称
        xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的
    ​
        //  onUploadProgress 允许为上传处理进度事件
        onUploadProgress: function (progressEvent) {
            // 对原生进度事件的处理
        },
    ​
        //  onDownloadProgress 允许为下载处理进度事件
        onDownloadProgress: function (progressEvent) {
            // 对原生进度事件的处理
        },
    ​
        //  maxContentLength 定义允许的响应内容的最大尺寸
        maxContentLength: 2000,
    ​
        //  validateStatus 定义对于给定的HTTP 响应状态码是 resolve 或 reject  promise 。
        // 如果 validateStatus 返回 true (或者设置为 null 或 undefined ),promise 将被 resolve; 否则,promise 将被 rejecte
        validateStatus: function (status) {
            return status >= 200 && status < 300; // 默认的
        },
    ​
        //  maxRedirects 定义在 node.js 中 follow 的最大重定向数目
        // 如果设置为0,将不会 follow 任何重定向
        maxRedirects: 5, // 默认的
    ​
        //  httpAgent 和 httpsAgent 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
        //  keepAlive 默认没有启用
        httpAgent: new http.Agent({keepAlive: true}),
        httpsAgent: new https.Agent({keepAlive: true}),
    ​
        // 'proxy' 定义代理服务器的主机名称和端口
        //  auth 表示 HTTP 基础验证应当用于连接代理,并提供凭据
        // 这将会设置一个 Proxy-Authorization 头,覆写掉已有的通过使用 header 设置的自定义 Proxy-Authorization 头。
        proxy: {
            host: '127.0.0.1',
            port: 9000,
            auth: {
                username: 'lisi',
                password: '54321'
            }
        },
    ​
        //  cancelToken 指定用于取消请求的 cancel token
        cancelToken: new CancelToken(function (cancel) {
        })
    }

     

    五、响应内容

    {
      data:{},
      status:200,
      //从服务器返回的http状态文本
      statusText:'OK',
      //响应头信息
      headers: {},
      //config是在请求的时候的一些配置信息
      config: {}
    }

    可以这样来获取响应信息

    <input id="getId" type="button" value="get"/>
    <script>
        $("#getId").click(function () {
            axios.get('http://localhost:8080/user/findById?id=1')
                .then(function (value) {
                    console.log("data:"+value.data);
                    console.log("status:"+value.status);
                    console.log("statusText:"+value.statusText);
                    console.log("headers:"+value.headers);
                    console.log("config:"+value.config);
                })
                .catch(function (reason) {
                    console.log(reason);
                })
        })
    </script>

     

    六、默认配置

    默认配置对所有请求都有效

    1、全局默认配置

    axios.defaults.baseURL = 'http://localhost:8080/';
    axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
    axios.defaults.headers.post['content-Type'] = 'appliction/x-www-form-urlencoded';

    2、自定义的实例默认设置

    //当创建实例的时候配置默认配置
    var instance = axios.create({
        baseURL: 'http://localhost:8080/'
    });
    //当实例创建时候修改配置
    instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;

    3、配置中有优先级

    • config配置将会以优先级别来合并,顺序是lib/defauts.js中的默认配置,然后是实例中的默认配置,最后是请求中的config参数的配置,越往后等级越高,后面的会覆盖前面的例子。

    //创建一个实例的时候会使用libray目录中的默认配置
    //在这里timeout配置的值为0,来自于libray的默认值
    var instance = axios.create();
    //回覆盖掉library的默认值
    //现在所有的请求都要等2.5S之后才会发出
    instance.defaults.timeout = 2500;
    //这里的timeout回覆盖之前的2.5S变成5s
    instance.get('/longRequest',{
      timeout: 5000
    });

     

    七、拦截器

    1.可以在请求、响应在到达then/catch之前拦截

    //添加一个请求拦截器
    axios.interceptors.request.use(function(config){
      //在请求发出之前进行一些操作
      return config;
    },function(err){
      //Do something with request error
      return Promise.reject(error);
    });
    //添加一个响应拦截器
    axios.interceptors.response.use(function(res){
      //在这里对返回的数据进行处理
      return res;
    },function(err){
      //Do something with response error
      return Promise.reject(error);
    })

    2.取消拦截器

    var myInterceptor = axios.interceptor.request.use(function(){/*....*/});
    axios.interceptors.request.eject(myInterceptor);

    3.给自定义的axios实例添加拦截器

    var instance = axios.create();
    instance.interceptors.request.use(function(){})

     

    八、错误处理

    <input id="getId" type="button" value="get"/>
    <script>
        $("#getId").click(function () {
            axios.get('http://localhost:8080/user/findById?id=100')
                .catch(function (error) {
                    if (error.response) {
                        //请求已经发出,但是服务器响应返回的状态吗不在2xx的范围内
                        console.log("data:"+error.response.data);
                        console.log("status:"+error.response.status);
                        console.log("header:"+error.response.header);
                    } else {
                        //一些错误是在设置请求的时候触发
                        console.log('Error', error.message);
                    }
                    console.log(error.config);
                });
        })
    </script>

     

    九、取消

    通过一个cancel token来取消一个请求

    通过CancelToken.source工厂函数来创建一个cancel token

    <input id="getId" type="button" value="get"/>
    <input id="unGetId" type="button" value="unGet"/>
    <script>
        var CancelToken = axios.CancelToken;
        var source = CancelToken.source();
        $("#getId").click(function () {
            axios.get('http://localhost:8080/user/findById?id=1', {
                cancelToken: source.token
            })
                .then(function (value) {
                    console.log(value);
                })
                .catch(function (thrown) {
                if (axios.isCancel(thrown)) {
                    console.log('Request canceled', thrown.message);
                } else {
                    //handle error
                }
            });
        });
        $("#unGetId").click(function () {
            //取消请求(信息的参数可以设置的)
            source.cancel("操作被用户取消");
        });
    </script>

     

    展开全文
  • Vue之Axios跨域问题解决方案

    万次阅读 多人点赞 2019-02-19 14:32:31
    背景:因为axios中只能使用get和post方法来进行请求数据,没有提供jsonp等方法进行跨域访问数据 axios中文网址:https://www.kancloud.cn/yunye/axios/234845 // axios 中的GET请求 axios.get('/user', { ...

    背景:因为axios中只能使用get和post方法来进行请求数据,没有提供jsonp等方法进行跨域访问数据

              axios中文网址:https://www.kancloud.cn/yunye/axios/234845

    // axios 中的GET请求
    axios.get('/user', {
        params: {
          ID: ‘001’
        }
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    
    // axios 中的POST请求
    axios.post('/user', {
        firstName: '1',
        lastName: '2'
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    

    方案1:既然使用axios直接进行跨域访问不可行,我们就需要配置代理了。代理可以解决的原因:因为客户端请求服务端的数据是存在跨域问题的,而服务器和服务器之间可以相互请求数据,是没有跨域的概念(如果服务器没有设置禁止跨域的权限问题),也就是说,我们可以配置一个代理的服务器可以请求另一个服务器中的数据,然后把请求出来的数据返回到我们的代理服务器中,代理服务器再返回数据给我们的客户端,这样我们就可以实现跨域访问数据。

    准备工作:安装所需中间件和插件等,比如axios,http-proxy-middleware等。

    具体案例:这里以访问豆瓣Top250为例,直接访问如下:

    axios.get("http://api.douban.com/v2/movie/top250")
    .then(res=>{
    	console.log(res)
    })
    .catch(err=>{
    	console.log(err)
    })
    

    当执行npm run dev时,控制台报错如下:

    事实证明直接请求确实出现跨域问题了,下面具体演示解决跨域问题的步骤:

    上面所说的必备条件都已安装完成的情况下,执行以下步骤即可解决问题:

    1.配置BaseUrl

    在main.js中,配置数据所在服务器的前缀(即固定部分),代码如下:

    // 项目入口,配置全局vue
    import Vue from 'vue'
    import VueRouter from './router/routes.js'
    import Store from './store/index.js'
    
    import './assets/less/index.less'
    import App from './App.vue'
    
    
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-default/index.css'
    
    import axios from 'axios'
    Vue.prototype.$axios = axios
    axios.defaults.baseURL = '/api'  //关键代码
    Vue.config.productionTip = false
    
    
    Vue.use(ElementUI);
    
    new Vue({
    	router:VueRouter,
    	store:Store,
    	template:'<App/>',
    	components: {App}
    }).$mount('#app')
    
    // 默认进入商品模块
    // VueRouter.push({ path: '/home' })
    

    关键代码:axios.defaults.baseURL = '/api',作用是我们每次发送的请求都会带一个/api的前缀。

    2.配置代理

    在config文件夹下的index.js文件中的proxyTable字段中,作如下处理:

      dev: {
        env: require('./dev.env'),
        port: 8090,
        autoOpenBrowser: true,
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        proxyTable: {
          '/api': {
            target:'http://api.douban.com/v2', // 你请求的第三方接口
            changeOrigin:true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
            pathRewrite:{  // 路径重写,
              '^/api': ''  // 替换target中的请求地址,也就是说以后你在请求http://api.douban.com/v2/XXXXX这个地址的时候直接写成/api即可。
            }
          }
        },
        // CSS Sourcemaps off by default because relative paths are "buggy"
        // with this option, according to the CSS-Loader README
        // (https://github.com/webpack/css-loader#sourcemaps)
        // In our experience, they generally work as expected,
        // just be aware of this issue when enabling this option.
        cssSourceMap: false
      }

    3.在具体使用axios的地方,修改url如下即可:

     axios.get("/movie/top250").then((res) => {
                      res = res.data
                      if (res.errno === ERR_OK) {
                         this.themeList=res.data;
                      }
                    }).catch((error) => {
                      console.warn(error)
                    })

    4.重新启动项目之后,已经解决了跨域问题,结果如下:

    原理:

    因为我们给url加上了前缀/api,我们访问/movie/top250就当于访问了:localhost:8080/api/movie/top250(其中localhost:8080是默认的IP和端口)。

    在index.js中的proxyTable中拦截了/api,并把/api及其前面的所有替换成了target中的内容,因此实际访问Url是http://api.douban.com/v2/movie/top250。

    至此,纯前端配置代理解决axios跨域得到解决。

    方案2:后端处理跨域问题,加个过滤器即可解决,如下:

    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * 跨域过滤器
     * @author jitwxs
     * @since 2018/10/16 20:53
     */
    public class CorsFilter implements Filter {
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest) req;
    
            // 不使用*,自动适配跨域域名,避免携带Cookie时失效
            String origin = request.getHeader("Origin");
            if(StringUtils.isNotBlank(origin)) {
                response.setHeader("Access-Control-Allow-Origin", origin);
            }
    
            // 自适应所有自定义头
            String headers = request.getHeader("Access-Control-Request-Headers");
            if(StringUtils.isNotBlank(headers)) {
                response.setHeader("Access-Control-Allow-Headers", headers);
                response.setHeader("Access-Control-Expose-Headers", headers);
            }
    
            // 允许跨域的请求方法类型
            response.setHeader("Access-Control-Allow-Methods", "*");
            // 预检命令(OPTIONS)缓存时间,单位:秒
            response.setHeader("Access-Control-Max-Age", "3600");
            // 明确许可客户端发送Cookie,不允许删除字段即可
            response.setHeader("Access-Control-Allow-Credentials", "true");
            
            chain.doFilter(request, response);
        }
    
        @Override
        public void init(FilterConfig filterConfig) {
    
        }
    
        @Override
        public void destroy() {
        }
    
        /*
        注册过滤器:
        @Bean
        public FilterRegistrationBean registerFilter() {
            FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>();
            bean.addUrlPatterns("/*");
            bean.setFilter(new CorsFilter());
            // 过滤顺序,从小到大依次过滤
            bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    
            return bean;
        }
         */
    }
    

    以上axios解决跨域的方案,希望能解决大家遇到的跨域问题,如有问题请添加评论。

    -------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------

    根据评论区内容,区分一下生产环境和开发环境,集体配置如下:

    1.在config文件夹里面创建一个api.config.js的配置文件

    const isPro = Object.is(process.env.NODE_ENV, 'production')
    
    console.log(isPro);
    
    module.exports = {
      baseUrl: isPro ? 'https://www.***/index.php/Official(线上地址)' : 'api/'
    }

    2.在main.js文件里面引入上面文件,这样就可以保证动态的匹配生产和开发环境的定义前缀了,代码如下:

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import 'bootstrap/dist/js/bootstrap.min'
    import 'bootstrap/dist/css/bootstrap.min.css'
    import axios from 'axios'
    import apiConfig from '../config/api.config'
    
    Vue.prototype.$axios = axios;
    Vue.config.productionTip = false;
    axios.defaults.baseURL = apiConfig.baseUrl;// 配置接口地址
    axios.defaults.withCredentials = false;

    以上两步即可解决vue的跨域问题,并且可以可以直接build打包到线上,如有问题,请评论区留言,希望对你有所帮助。

    展开全文
  • vue项目的前期配置 封装axios实例 封装API

    前言

    在做vue中大型项目的时候,官方推荐使用axios,但是原生的axios可能对项目的适配不友好,所以,在工程开始的来封装一下axios,保持全项目数据处理的统一性。此文主要讲在vue-cil项目中如何封装axios,封装请求,封装公共的api,页面如何调用请求。

    如果你能看到这篇文章,鉴于有很多小白可能会参考我这篇文章来进行前期配置,特说明下正式配置路线:

    1. 拿到项目及后台接口,首先做的是配置全局代理及第二点
    2. 全局封装axios及第三点request.js;
    3. 过滤axios请求方式,控制路径及参数的格式及第四点http.js;
    4. 正式封装api及第五点api.js;
    5. 页面调用;

    正文

    一、vue项目的前期配置

    新建vue项目,下载axios,并在main.js中导入axios

    npm i axios -S
    
    //main.js
    import axios from "axios";
    

    二、配置config文件中的代理地址

    在项目config目录下的修改 index.js文件,这里是主要书写配置多个后台接口。关于代理可能出现的问题,可以查看我的另一篇文档VueCil代理本地proxytable报错的解析

    vue cil2旧版本的代理配置——config/index.js

     dev: {
        // Paths
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        // 后端请求地址代理,配置后testIp再之后的页面调用时就直接指代 http://197.82.15.15:8088
        proxyTable: {
          '/testIp': {
            target: 'http://197.82.15.15:8088',
            changeOrigin: true,
            pathRewrite: { 
              '^/testIp': ''
            }
          },
          '/elseIp': {
            target: 'http://182.83.19.15:8080',
            changeOrigin: true,
            pathRewrite: { 
              '^/esleIp': ''
            }
          },
        },
    
        // Various Dev Server settings
        host: 'localhost', // can be overwritten by process.env.HOST
        port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
        autoOpenBrowser: false,
        errorOverlay: true,
        notifyOnErrors: true,
        poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
    
    
        /**
         * Source Maps
         */
    
        // https://webpack.js.org/configuration/devtool/#development
        devtool: 'cheap-module-eval-source-map',
    
        // If you have problems debugging vue-files in devtools,
        // set this to false - it *may* help
        // https://vue-loader.vuejs.org/en/options.html#cachebusting
        cacheBusting: true,
    
        cssSourceMap: true
      },
    
    

    vuecil 3+ 新版本的代理配置–vue.config.js 文件

    关于多代理配置:

    		 devServer: {
                overlay: { // 让浏览器 overlay 同时显示警告和错误
                  warnings: true,
                  errors: true
                },
                host: "localhost",
                port: 8080, // 端口号
                https: false, // https:{type:Boolean}
                open: false, //配置后自动启动浏览器
                hotOnly: true, // 热更新
                // proxy: 'http://localhost:8080'   // 配置跨域处理,只有一个代理
                proxy: { //配置多个代理
                    "/testIp": {
                        target: "http://197.0.0.1:8088",
                        changeOrigin: true,
                        ws: true,//websocket支持
                        secure: false,
                        pathRewrite: {
                            "^/testIp": "/"
                        }
                    },
                    "/elseIp": {
                        target: "http://197.0.0.2:8088",
                        changeOrigin: true,
                        //ws: true,//websocket支持
                        secure: false,
                        pathRewrite: {
                            "^/elseIp": "/"
                        }
                    },
                }
            }
    

    其中vue.config.js详细参考我另一篇博客:vue项目升级(01):全面解析vuecil3/vuecil4的vue.config.js等常用配置

    如果有多后台,就可以在api文件夹下另外新建一个elseApi.js ,书写当前ip下的接口请求。方法同上,只是 let resquest = "/elseIp/request/" 调用的时候把端口更改一下。

    三、封装axios实例 —— request.js

    在项目src目录下新建utils文件夹,然后在其中新建 request.js文件,这个文件是主要书写axios的封装过程。

    /****   request.js   ****/
    // 导入axios
    import axios from 'axios'
    // 使用element-ui Message做消息提醒
    import { Message} from 'element-ui';
    //1. 创建新的axios实例,
    const service = axios.create({
      // 公共接口--这里注意后面会讲
      baseURL: process.env.BASE_API,
      // 超时时间 单位是ms,这里设置了3s的超时时间
      timeout: 3 * 1000
    })
    // 2.请求拦截器
    service.interceptors.request.use(config => {
      //发请求前做的一些处理,数据转化,配置请求头,设置token,设置loading等,根据需求去添加
       config.data = JSON.stringify(config.data); //数据转化,也可以使用qs转换
       config.headers = {
         'Content-Type':'application/x-www-form-urlencoded' //配置请求头
       }
       //注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
       const token = getCookie('名称');//这里取token之前,你肯定需要先拿到token,存一下
       if(token){
          config.params = {'token':token} //如果要求携带在参数中
          config.headers.token= token; //如果要求携带在请求头中
        }
      return config
    }, error => {
      Promise.reject(error)
    })
    
    // 3.响应拦截器
    service.interceptors.response.use(response => {
      //接收到响应数据并成功后的一些共有的处理,关闭loading等
      
      return response
    }, error => {
       /***** 接收到异常响应的处理开始 *****/
      if (error && error.response) {
        // 1.公共错误处理
        // 2.根据响应码具体处理
        switch (error.response.status) {
          case 400:
            error.message = '错误请求'
            break;
          case 401:
            error.message = '未授权,请重新登录'
            break;
          case 403:
            error.message = '拒绝访问'
            break;
          case 404:
            error.message = '请求错误,未找到该资源'
            window.location.href = "/NotFound"
            break;
          case 405:
            error.message = '请求方法未允许'
            break;
          case 408:
            error.message = '请求超时'
            break;
          case 500:
            error.message = '服务器端出错'
            break;
          case 501:
            error.message = '网络未实现'
            break;
          case 502:
            error.message = '网络错误'
            break;
          case 503:
            error.message = '服务不可用'
            break;
          case 504:
            error.message = '网络超时'
            break;
          case 505:
            error.message = 'http版本不支持该请求'
            break;
          default:
            error.message = `连接错误${error.response.status}`
        }
      } else {
        // 超时处理
        if (JSON.stringify(error).includes('timeout')) {
          Message.error('服务器响应超时,请刷新当前页')
        }
        error.message = '连接服务器失败'
      }
    
      Message.error(error.message)
      /***** 处理结束 *****/
      //如果不需要错误处理,以上的处理过程都可省略
      return Promise.resolve(error.response)
    })
    //4.导入文件
    export default service
    

    特殊说明:

    鉴于有很多朋友问关于数据转换这块的问题,特在页面中单独回复一下!

    config.data = JSON.stringify(config.data);
    config.headers = { 'Content-Type':'application/x-www-form-urlencoded'  }
    const token = getCookie('名称')
    if(token){ 
      config.params = {'token':token} ; 
      config.headers.token= token; 
    }
    

    上述的代码都是请求的配置项,非必须,也是分情况的,data/headers /params 这种本身的参数都有多种,和后台沟通,需要什么就配什么!
    config.data = JSON.stringify(config.data);为什么不用qs.stringify,因为我的后台想要的只是json类型的传参,而qs转换会转换成为键值对拼接的字符串形式。当然你们后台需要传递字符串类型参数,那就换成qs或者其他格式方式。
    const token = getCookie('名称')这是token的取值,在取之前你肯定需要发请求拿到token,然后setCookie存起来,而名称就是你存的token的名称,每个人的不一样;
    config.headers = { 'Content-Type':'application/x-www-form-urlencoded' }请求头内容的配置,也是不同的,application/x-www-form-urlencoded :form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式),你可以根据实际情况去配置自己需要的;
    以上
    我已经举了很清晰的例子,写代码的过程是自己动脑去搭建工程的,希望能看到我文章的各位,善于搜索,善于思考,善于总结;
    当然我很喜欢帮大家解决问题,但是相关的基础问题,还是建议自己去学习掌握。

    四、封装请求——http.js

    在项目src目录下的utils文件夹中新建 http.js文件,这个文件是主要书写几种请求的封装过程。

    /****   http.js   ****/
    // 导入封装好的axios实例
    import request from './request'
    
    const http ={
        /**
         * methods: 请求
         * @param url 请求地址 
         * @param params 请求参数
         */
        get(url,params){
            const config = {
                method: 'get',
                url:url
            }
            if(params) config.params = params
            return request(config)
        },
        post(url,params){
            const config = {
                method: 'post',
                url:url
            }
            if(params) config.data = params
            return request(config)
        },
        put(url,params){
            const config = {
                method: 'put',
                url:url
            }
            if(params) config.params = params
            return request(config)
        },
        delete(url,params){
            const config = {
                method: 'delete',
                url:url
            }
            if(params) config.params = params
            return request(config)
        }
    }
    //导出
    export default http
    

    五、正式封装API,用于发送请求——api.js

    在项目src目录下新建api文件夹,然后在其中新建 api.js文件,这个文件是主要书写API的封装过程。

    写法一:适合分类导出

    import http from '../utils/http'
    // 
    /**
     *  @parms resquest 请求地址 例如:http://197.82.15.15:8088/request/...
     *  @param '/testIp'代表vue-cil中config,index.js中配置的代理
     */
    let resquest = "/testIp/request/"
    
    // get请求
    export function getListAPI(params){
        return http.get(`${resquest}/getList.json`,params)
    }
    // post请求
    export function postFormAPI(params){
        return http.post(`${resquest}/postForm.json`,params)
    }
    // put 请求
    export function putSomeAPI(params){
        return http.put(`${resquest}/putSome.json`,params)
    }
    // delete 请求
    export function deleteListAPI(params){
        return http.delete(`${resquest}/deleteList.json`,params)
    }
    
    

    写法二:使用全部导出

    import http from '../utils/http'
    // 
    /**
     *  @parms resquest 请求地址 例如:http://197.82.15.15:8088/request/...
     *  @param '/testIp'代表vue-cil中config,index.js中配置的代理
     */
    let resquest = "/testIp/request/"
    
    // get请求
    export default{
     	getListAPI(params){
        	return http.get(`${resquest}/getList.json`,params)
    	},
    	 postFormAPI(params){
        	return http.post(`${resquest}/postForm.json`,params)
    	}
    }
    

    注意:一个项目中如果后台请求不是同一个ip,而是多个ip的时候,可以在api文件夹下建立多个js,用来调用请求。
    我们看下之前遗留的一个问题:

    //创建新的axios实例,
    const service = axios.create({
      baseURL: process.env.BASE_API,
      timeout: 3 * 1000
    })
    

    在之前封装公共接口的baseUrl时候,用了webpack中的全局变量process.env.BASE_API,而不是直接写死ip,也是为了适应多个后台或者开发的时候的api地址和发布的时候的api地址不一样这种情况。

    以上 关于配置环境 和接口 基本搭建完毕,下面看一下调用:

    六、如何在vue文件中调用

    方法一:用到哪个api 就调用哪个接口——适用于上文接口分类导出;

     import {getListAPI,postFormAPI, putSomeAPI, deleteListAPI} from '@/api/api'
    
      methods: {
          //promise调用,链式调用, getList()括号内只接受参数;
          //   get不传参
          getList() {
            getListAPI().then(res => console.log(res)).catch(err => console.log(err))
          },
    		//post传参
          postForm(formData) {
            let data = formData
            postFormAPI(data).then(res => console.log(res)).catch(err => console.log(err))
          },
    
          //async await同步调用
          async postForm(formData) {
            const postRes = await postFormAPI(formData)
            const putRes = await putSomeAPI({data: 'putTest'})
            const deleteRes = await deleteListAPI(formData.name)
            // 数据处理
            console.log(postRes);
            console.log(putRes);
            console.log(deleteRes);
          },
       }
    

    方法二 :把api全部导入,然后用哪个调用哪个api——适用于全部导出

       import api from '@/api/api'
       methods: {
         getList() {
            api.getListAPI(data).then(res => {
              //数据处理
            }).catch(err => console.log(err))
          }
        }  
    

    结语

    以上就详细介绍了,在vue-cil项目中 如何封装axios,封装请求,封装公共的api,配置多个接口,页面如何调用请求等问题,都是亲测有用的~ 但是这种封装方法的话,更适合大中型项目,配置比较合理,如果是自己小项目,就直接用axios就完事了。。。

    补充

    如果本文对你有帮助的话,请不要忘记给我点赞打call哦~o( ̄▽ ̄)do
    有其他问题留言 over~

    展开全文
  • vue axios封装 axios 请求

    2020-03-27 15:04:31
    vue axios封装 axios 请求
  • axios基本用法

    万次阅读 多人点赞 2018-03-28 14:23:50
    一.axios1.什么是axiosaxios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端。简单的理解就是ajax的封装它本身具有以下特征: a.从浏览器中创建 XMLHttpRequest b.从 node.js 发出 http 请求 c.支持 Promise...
  • vue-axios的使用及其get与post网络请求

    万次阅读 多人点赞 2018-06-23 02:39:20
    一、vue-axios学习网址 网址1: https://github.com/imcvampire/vue-axios 网址2: https://www.npmjs.com/packge/axios 二、vue中get与post请求 vue高版本中,推荐使用axios进行网络请求,而不再使用vue-...
  • axios拦截器,二次封装axios
  • axios详解

    万次阅读 多人点赞 2020-05-25 10:47:26
    文章目录axios是干啥的原生XMLHttpRequest实现axios介绍发送并发请求axios API创建一个实例Config配置选项默认设置全局默认设置实例中自定义默认值设置的优先级响应信息(response schema)拦截器interceptors错误处理...
  • axios的使用

    万次阅读 多人点赞 2019-06-10 23:14:46
    首先要在项目目录下使用如下命令下载axios $npm i axios -S 而后在src目录下创建requests文件夹,里面用来存放你整个项目的ajax请求。 此文件夹中首先创建一个index.js文件 编写里面的内容: //引入axios import ...
  • vue axios同步请求解决方案

    万次阅读 2017-09-28 21:53:01
    在vue项目里面,需要循环发送ajax请求,出现的问题就是循环结束,第一次服务器还没返回,导致数据处理错误,需要使用同步请求解决方案目前没有发现axios可以同步请求,所以只能使用jQuery,配置同步请求;...
  • axios 封装

    2018-12-11 14:28:29
    Vue axios 二次封装 多种请求自适应 ** Fn: axios ** Intro: 公用封装的axios 已在main.js中进行 $axios代理 ** Intro: Store.state.permission.constUrl 为公用的接口前缀地址 ** Intro: url 方法接受参数 为...
  • 细谈 axios和ajax区别

    万次阅读 多人点赞 2019-03-11 18:00:53
    刚刚接触axios有好多疑惑。它和ajax有什么关系呢和区别呢?接下来一起看下: 1.区别 axios是通过promise实现对ajax技术的一种封装,就像jQuery实现ajax封装一样。 简单来说: ajax技术实现了网页的局部数据刷新,...
  • Axios记录器 美化Axios日志记录消息。 在nodejs中发送请求时,需要将日志显示到控制台。 与服务器通信时,该库显示必要的信息。 基本上,此软件包可以用作。 安装 $ npm install axios-logger --save-dev 如何...
  • react-axios:React和Axios
  • Axios是不允许跨域访问的,别说跨域,跨端口都不行。例如某项目我本地vue前端frontEnd为`localhost:8888`,Java后台 backEnd为`localhost:8889` 。 这个时候就有两个方案了: - 修改`frontEnd`前端,支持跨域(通过...
  • sea-axios sea-axios (v2.0.0以上) 是为了简化使用,基于 axios (v0.18.0) 封装的一套 http 工具库。 功能 简化一些常用请求方式的封装。 提供基于全局的请求配置项。 开启 debug 可以显示请求响应耗时。 提供 axios...
  • Axios更好的堆栈跟踪 Axios插件,可为axios错误提供更好的堆栈跟踪。 有关更多详细信息,。 安装 NPM npm install axios-better-stacktrace 纱 yarn add axios-better-stacktrace 笔记 已使用axios 0.21.0进行了...
  • axios和vue-axios区别及vue-axios使用

    千次阅读 2019-10-21 19:17:46
    一、axios和vue-axios区别 1、axios是基于promise的HTTP库,可以使用在浏览器和node.js中,它不是vue的第三方插件 2、使用的时候不能像vue的插件(如:Vue-Router、VueX等)通过Vue.use()安装插件,需要在原型上进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 131,032
精华内容 52,412
关键字:

axios