Vue使用axios、解决axios跨域

axios

axios文档

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF
    看起来就很高大上,就决定是它了;但用起来脑子石化,一脸黑人问号,经脉逆流…但是惹不起还是得惹,毕竟它非常流行
axios使用处理错误的写法
  1. 一个不建议的处理发生错误的代码
	axios.get(url)
    .then(response => {
        console.log(response);
    }, error => {
        console.log(error);
    })

这不是处理catch的相关,是关于new Promise()的then,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
2. catch是处理逻辑或接口出错

axios.get(url)
.then(res=>{
//处理业务逻辑
})
.catch(err=>{

})
  1. catch的分步骤处理
    if (error.response) {
// 请求已发出,但服务器响应的状态码不在 2xx 范围内
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // 有请求但未收到响应
      console.log(error.request);
    } else {
      // 在发生请求时触发的错误
      console.log('Error', error.message);
    }
    console.log(error.config);

vue cli 2使用axios

  1. 安装脚手架
cnpm install -g @vue/cli-service-global
  1. 现在是vue cli 3,所以我们需要全局安装一个桥接工具
cnpm install -g @vue/cli-init
  1. 可以自主选择,根据自己需求,这里选择默认的,然后下载包,最后更改App.vue的内容
vue init webpack axios_test
cnpm i 
  1. 下载axios
cnpm i axios -S
  1. 提供接口:这里使用某度音乐做测试接口
http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0
  1. 在main.js导入并配置
import Axios from 'axios'
Vue.prototype.$axios  = Axios
  1. App.vue测试
export default {
  mounted(){
    this.$axios.get('http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0')
    .then(result=>{
      console.log(result)
    })
    .catch(error=>{
      console.log(error)
    })
  }
};
  1. 运行项目
cnpm run dev

我用铜钱算出来你报了一下的错误;这是因为浏览器的同源政策

Access to XMLHttpRequest at 'http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
解决跨域

我们先来实现解决跨域在解释(1.2是实现解决禁止跨域的)

  1. 在main.js加入HOST
Vue.prototype.$axios  = Axios
Vue.prototype.HOST = '/baidu_music_api'
  1. 在配置文件config文件夹的index.js里面配置,在里面有个proxyTable配置
    proxyTable: {
      "/baidu_music_api": {
        target: "http://tingapi.ting.baidu.com",
        changeOrigin: true,
        pathRewrite: {
            '^/baidu_music_api': '/v1/restserver/ting'
        }
    }
    },
  1. 重新再App.vue发送请求
  mounted(){
    let url = this.HOST + '?method=baidu.ting.billboard.billList&type=1&size=10&offset=0'
    this.$axios.get(url)
    .then(result=>{
      console.log(result)
    })
    .catch(error=>{
      console.log(error)
    })
  1. 配置文件的解释
    proxyTable在使用webpack做构建工具的项目中使用proxyTable代理实现跨域是一种比较方便的选择。
    target目标接口域名
    changeOrigin是否跨域
    pathRewrite是重写接口,如果没有包含该项目名或则字段(/v1/restserver/ting)的话,我们可以直接写’/'来代替

比如大部分接口有’api’,我们配置的时候时候可以直接(这里跟我们当前接口使用的无关)

proxyTable: {
    '/api': {
      target: 'http://www.csdn.com',  //目标接口域名
      changeOrigin: true,  //是否跨域
      pathRewrite: {
        '^/api': '/api'   //重写接口
        //没有api
        // '^api':'/'
      }
    },
  1. 原理解释
'http://localhost:8080/baidu_music_api' ===> 'http://tingapi.ting.baidu.com/v1/restserver/ting'
本地服务器 --》 代理 --》目标服务器 --》拿到数据后通过代理伪装成本地服务请求的返回值 ---》然后浏览器就顺利收到了我们想要的数据

也就是说我们访问,会重写服务器http://tingapi.ting.baidu.com,baidu_music_api就会解析成v1/restserver/ting;有人说可以理解为服务器是没有同源政策的。
6. 接下来可以看一下我们返回的数据,直接截图
在这里插入图片描述
以下响应结构的信息;所以我们的数据都要在data里面获取

{
  // `data` 由服务器提供的响应
  data: {},
  // `status` 来自服务器响应的 HTTP 状态码
  status: 200,
  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: 'OK',
  // `headers` 服务器响应的头
  headers: {},
  // `config` 是为请求提供的配置信息
  config: {}
}
  1. 添加拦截器
    页面发送http请求,很多情况我们要对请求和其响应进行特定的处理;如果请求数非常多,单独对每一个请求进行处理会变得非常麻烦,程序的优雅性也会大打折扣。axios为开发者提供了这样一个API:拦截器。拦截器分为 请求(request)拦截器和 响应(response)拦截器。
    应用场景:路由拦截、统一处理所有的http请求和响应、refresh_token换access_token
Vue.prototype.HOST = '/baidu_music_api'
// 添加请求拦截器
Axios.interceptors.request.use(function (config) {
    if(config.method === "post"){
      config.data = qs.stringify(config.data)
    }
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
Axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

vue cli3使用

vue cli参考配置vue.config.js的devServer配置
可以自主配置(空格是选中),也可以直接选择默认

vue create axios_vue3
  1. 项目根目录下新建vue.config.js
    vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。
  2. 接着在main.js的文档里面配置(先安装axios)
import Axios from 'axios'
Vue.prototype.$axios  = Axios
Vue.prototype.HOST = '/api'
  1. 在vue.config.js里面配置
module.exports = {
devServer: {
    proxy: {
      '/api': {
        target: 'http://tingapi.ting.baidu.com/v1/restserver/ting',
        ws: true,
        changeOrigin: true
      }
    }
  }
}
  1. 测试axios
  mounted(){
   let url = this.HOST + '?method=baidu.ting.billboard.billList&type=1&size=10&offset=0'
   this.$axios.get(url).then(result=>{
    console.log(result)
   })
  }

结果

直接使用webpack,没有使用脚手架的,看看这个能否解决

https://webpack.js.org/configuration/dev-server/#devserverproxy

你可能感兴趣的:(webpack,vue)