2018-07-13 11:33:55 YU_M_K 阅读数 6499
1:简单介绍及安装

        Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

         安装:npm install axios
2:地址

       https://www.kancloud.cn/yunye/axios/234845

3:get请求

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 可选地,上面的请求可以这样做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
4:执行post请求
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
5:执行多个并发请求
function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));


2017-09-15 13:35:59 feifanzhuli 阅读数 42703

在这里插入图片描述

安装


使用 npm:

$ npm install axios -S

或者 使用 bower:

$ bower install axios

或者直接使用 cdn:

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

main.js设置如下

引入axios

	import axios from 'axios'

挂载到vue的原型

	Vue.prototype.$http = axios

在组件内使用

	this.$http.get('/url',{params:{username:'张三'}})

在webpack.config.js(config—>index.js)文件里设置代理

dev: {
    env: require('./dev.env'),
    port: 8080,  //设置访问的端口号
    autoOpenBrowser: true, //自动打开浏览器
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
        '/api': {
            target: 'http://10.10:8063', //设置调用接口域名和端口号别忘了加http
            changeOrigin: true,
            pathRewrite: {
                '^/api': '/' //这里理解成用‘/api’代替target里面的地址,组件中我们调接口时直接用/api代替
                    // 比如我要调用'http://0.0:300/user/add',直接写‘/api/user/add’即可 代理后地址栏显示/
            }
        }
    }

执行 GET 请求

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 可选地,上面的请求可以这样做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行 POST 请求

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

执行多个并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));

创建实例
可以使用自定义配置新建一个 axios 实例
axios.create([config])

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

参考使用说明API:https://www.kancloud.cn/yunye/axios/234845

结束语:

《窗花》
文/非凡主力
旭日初露落凉台,淡淡窗花笑冉开。
红梅不畏北风寒,只源暖意心中来。
二零一四年 • 冬

打赏作者:
这里写图片描述

2019-08-26 21:40:57 weixin_43764814 阅读数 2533

因为vue-resource不在更新,vue推荐使用axios,所以使用axios。
在页面交互过程中,发现axios一定几率会发送两次请求,一次是自己设置的请求方式,还有一次是options。
关于这个问题,在各个网站寻求原因,得出以下结论:
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
也就是说,它会先使用options去测试,你这个接口是否能够正常通讯,如果不能就不会发送真正的请求过来,如果测试通讯正常,则开始正常请求。
关于这个问题,需要在后台进行设置,允许options请求,不然你的请求就会受到影响,后台并作出判断,如果请求方式为options,告诉它可以通讯,其他直接什么都不做。
以下是PHP做设置内容
header(“Access-Control-Allow-Origin:*”);
header(“Access-Control-Allow-Headers:content-type”);
header(“Access-Control-Request-Method:GET,POST”);
if(strtoupper($_SERVER[‘REQUEST_METHOD’])== ‘OPTIONS’){
exit;
}

有些老php没有做过前后端分离,会直接甩锅给前端.时代在变化.必须不断学习才行.前端nuxt用(vue官方推荐的)axios发送post请求 php中做一下判断就可以了

 if(strtoupper($_SERVER['REQUEST_METHOD'])== 'OPTIONS'){
   echo 'options请求,已忽略。';
    exit; 
}

允许跨域不就是服务端设置Access-Control-Allow-Origin: *就可以了吗?普通的请求才是这样子的,除此之外,还一种叫请求叫preflighted request。
preflighted request在发送真正的请求前,会先发送一个方法为OPTIONS的预请 求(preflight request),用于试探服务端是否能接受真正的请求,如果options获得的回应是拒绝性质的,比如404\403\500等http状态,就会停post. put等请求的发出。
那么什么情况下请求会变成preflighted request呢?
1、请求方法不是GET/HEAD/POST
2、POST请求的Content -Type并非application/x-www-form-urlencoded, multipart/form-data,或text/plain3、请求设置了自定义的header字段
上面请求中设置了自定义的headers字段,出现了option请求。把自定义headers字段删掉后,只剩下get请求:

QQ技术交流群:634196762

2018-08-22 17:05:00 weixin_30755393 阅读数 0

本文只要介绍如何在项目中把react和axios结合起来使用,想了解更多关于axios详细知识以及api,可以到官网查看 https://www.npmjs.com/package/axios

首先安装 axios

$npm install axios  或  $yarn install axios

代码中引入axios

import axios from 'axios';

写一个拦截所有请求的axios全局拦截器

import axios from 'axios';
import globalCode from '../constants/globalCode'; 
import { Toast } from 'antd-mobile';
import {createHashHistory} from 'history';
import commonInfo from '../common/CommonInfo';

const instance = axios.create({
    //当创建实例的时候配置默认配置
    xsrfCookieName: 'xsrf-token'
});

//添加请求拦截器
instance.interceptors.request.use(function(config){
        //在发送请求之前做某事,比如加一个loading
        if(commonInfo.hasLoading){
            Toast.loading('', 3);
        }

        return config;
    },function(error){
        //请求错误时做些事
        Toast.hide();
        return Promise.reject(error);
});

//添加一个响应拦截器
instance.interceptors.response.use(function (response) {
    // 1.成功
    if (response.data.success && response.data.messageCode === globalCode.success) {
        if(commonInfo.hasLoading){
            Toast.hide();
        }
        return response.data.data;
    }

    // 2.session过期
    if (!response.data.success && response.data.messageCode === globalCode.timeout) {
        Toast.hide();
        Toast.info("会话过期,请重新登录", 1);
        createHashHistory().push('/login');

        // 定义一个messagecode在后面会用到
        return  Promise.reject({
            messageCode: 'timeout'
        })
    }

    // 3.11111111 系统异常、网络异常
    if (response.data.success && response.data.messageCode === globalCode.busyCode) {
        Toast.hide();
        Toast.info(response.data.message, 1);
        return  Promise.reject({
            messageCode: 'netError'
        })
    }

    // 3.其他失败,比如校验不通过等
    return Promise.reject(response.data);
}, function () {
    Toast.hide();
    // 4.系统错误,比如500、404等
    Toast.info('系统异常,请稍后重试!', 1);
    return Promise.reject({
        messageCode: 'sysError'
    });
});

export default instance;

引用 axios 的 instance 实例

mport API from '../../config/api';
import instance from '../utils/axiosCore';

// PS:此处如果对请求参数格式有疑问的可以查看官网资料,此处就不一一做详细解释了
// get
export const login = (params) => {
   return instance.get(API.LOGIN_API, { params: params });
};

// post
export const getConsultant = (params) => {
   return instance.post(API.GET_CONSULTANT_API, params);
};

发送请求并处理请求返回数据

import { login } from '../../models/loginModel';

login = () => {
        let params = {
           username: "admin",
           password: "123456"
        };
      
        login (params).then((data) => {
            //此处为正常业务数据的处理
           
        }, (data) => {
            if (data.messageCode !== 'netError' && data.messageCode !== 'sysError' && data.messageCode !== 'timeout') {
                //此处是对除了以上几个系统异常意外的业务异常的处理
                Toast.info(data.message, commonInfo.showToastTime);
            }
        });
    };


// 一次性并发多个请求
axios.all([getUserAccount(),getUserPermissions()])
  .then(axios.spread(function(acct,perms){
    //当这两个请求都完成的时候会触发这个函数,两个参数分别代表返回的结果
  }))

到此,就是一个完整的从请求发送->拦截请求->请求响应->拦截响应->处理返回数据。

 

上面的apis 文件可以用下面的方法写

封装一个匿名函数返回一个apis对象,通过apis对象的键名去获取对应的api地址

// 集中管理路由,所有的接口地址:
//  1.整个应用用到了哪些接口一目了然
//  2.接口地址可能变化,方便管理
​
const prefix = '' // api地址前缀
export default(config => {
    return Object.keys(config).reduce((copy, name) => {
      copy[name] = `${prefix}$config[name]`
      return copy
    })
})({
  // example api
  "getExampleData": "/api/example/data" 
})
​

文件最终返回一个对象

// api对象
{
  getExampleData: '/api/example/data'
}

 

转载于:https://www.cnblogs.com/xzqyun/p/9518882.html

2018-12-04 09:51:44 weixin_41845146 阅读数 2848

任何项目,只要支持axios,那么你只要把我现在封装的服务整个文件夹考过去即可。这个原本是我封装在vue里的,但是有一天公司突然来一个紧急的H5微信分享活动的项目,我当时用react搭建(zepto+node搭建其实最好)也是为了挑战一下自己,毕竟只有三天时间。所以当我把很多vue里封装的东西直接拷到react项目时,居然发现一点毛病都没有,我瞬间觉得自己好机智,之前没有怕浪费时间随便封装。其中包括axios服务,拷到react项目毫无毛病的就跑起来,surprise!!!

文件夹结构:

  • 原理就是获取导航栏地址然后正则匹配字符串
// config.js

let env = ''
if ((/env=online/.test(window.location.href))) {
  env = 'online'
} else if ((/env=dev/.test(window.location.href))) {
  env = 'dev'
} else {
  env = 'dev' // 默认环境
}
const SERVER_URL = {
  online: { // 正式环境
    SERVER_URL1: '',
    SERVER_URL2: '',
    SERVER_URL3: ''
  },
  dev: { // 测试环境
    SERVER_URL1: '',
    SERVER_URL2: '',
    SERVER_URL3: ''
  }
}
export default SERVER_URL[env]

env的功能是为了方便地址栏直接切换环境,开发时我们用的是后台的测试接口,上线时用的是线上接口,栗子:

  • 测试环境:http://0.0.0.0:8082/#/entry/entryIndex
  • 切换到
  • 正式环境:http://0.0.0.0:8082/?env=online/#/entry/entryIndex
     
  • 封装axios实例
  • 配置响应拦截/请求拦截
    • 响应拦截这儿主要就是处理一下后端传的code值,因为后台小哥哥老是这个传字符串那个传数字,心塞塞~
  • 并发请求
    • axios.all 是axios的静态方法,不是实例上的方法,所以要在实例上做操作

// interApi.js

import axios from 'axios'
import config from './config'

// 配置 axios,并生成实例
const creatAxios1 = axios.create({
  baseURL: config.SERVER_URL1,
  withCredentials: true
})

// 拦截器配置
creatAxios1.interceptors.request.use(configData => { // 请求拦截 在发送请求之前做些什么
  // 请求成功做的事情 configData 中包含:url、method等信息
  return configData
}, error => { // 请求失败做的事情
  return Promise.reject(error)
})

creatAxios1.interceptors.response.use(response => { // 响应拦截 对响应数据做点什么
  // 响应成功做的事情
  response.data.code = Number(response.data.code) // 将接口返回的状态值 code 处理为数字
  return response
}, error => { // 响应失败做的事情
  return Promise.reject(error)
})

function sendAll (arr) { // 顺序和请求发送的顺序相同,使用 axios.spread 分割成多个单独的响应对象
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    return axios.all(arr).then(axios.spread(function (...res) { // axios.all 是axios的静态方法,不是实例上的方法
      // 请求全部都执行完成
      return Promise.resolve(res)
    }))
  } else {
    const error = new Error('参数错误!')
    try {
      throw error
    } catch (e) {
      // console.log(e)
    }
  }
}

export default {
  creatAxios1,
  sendAll
}
  • 暴露 API 方法:get请求 post请求  并发请求
// extendsApi.js

/* eslint-disable no-useless-constructor */
import api from './interApi'
import qs from 'qs'
import config from './config'

function _apiFn (baseUrl) { // 该方法对外不可见
  if (baseUrl === 'service2') {
    api.creatAxios1.defaults.baseURL = config.SERVER_URL2 // 改变 axios 实例的 baseURL
  } else if (baseUrl === 'service3') {
    api.creatAxios1.defaults.baseURL = config.SERVER_URL3
  } else {
    api.creatAxios1.defaults.baseURL = config.SERVER_URL1
  }
}
class axiosApi {
  constructor () {

  }

  sendGet (url, params = {}, baseUrl) { // get 请求
    if (Object.prototype.toString.call(params) === '[object Object]') {
      _apiFn(baseUrl)
      return api.creatAxios1.get(url, {params: params})
    } else {
      const error = new Error('参数错误!')
      try {
        throw error
      } catch (e) {
        // console.log(e)
      }
    }
  }

  sendPost (url, params = {}, baseUrl) { // post 请求
    if (Object.prototype.toString.call(params) === '[object Object]') {
      _apiFn(baseUrl)
      return api.creatAxios1.post(url, qs.stringify(params))
    } else {
      const error = new Error('参数错误!')
      try {
        throw error
      } catch (e) {
        // console.log(e)
      }
    }
  }

  /**
   * 并发请求,同时发送多个请求,使用栗子:src/views/infoEntry/dragCard/dragCardService.js
   * 顺序和请求发送的顺序相同
   * @param {arr: [请求1,请求2...]}
   */

  sendAll (arr) { // 并发请求
    return new Promise((resolve, reject) => {
      api.sendAll(arr).then(res => {
        return resolve(res)
      })
    })
  }
}

export default axiosApi
  • 公共服务使用方法
// index.js

// commit API
import extendsApi from './extendsApi'

class AllServiceApi extends extendsApi {
  constructor () {
    super()
    this.demoUrl = ''
  }
  demoGet (params) {
    return this.sendGet(this.demoUrl, params).then(res => {
      return res.data
    })
  }
}

export default new AllServiceApi()
  • 组件中的使用方法

// commit API
import extendsApi from 'services/extendsApi'

class LoginServiceApi extends extendsApi {
  constructor () {
    super()
    this.demoUrl = ''
  }
  demoGet (params) {
    return this.sendGet(this.demoUrl, params).then(res => {
      return res.data
    })
  }
}

export default new LoginServiceApi()

全局公共服务/组件的私有服务,如上封装以及使用即可。