vue学习笔记6:解决axios每次都重复请求两次的问题

蛰伏已久 蛰伏已久 2018-09-04

实测已解决axios重复请求的问题

使用axios每次都会产生两次网络请求,第一次是Request Method为OPTIONS的请求,询问服务器是否有访问权限, 如果有,则再次请求数据,所以首先我们要知道,这不是bug,而是由于跨域通讯造成的,是符合w3c标准的。但是作为强迫证,不能忍受这种方式,而且感觉这种请求多出一次,也会造成一定的延迟,所以还是去掉为好。

核心是要将我们的请求改为简单请求的形式

我们先来看一下原理:

CORS跨域资源共享

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

对于简单请求,可以直接请求,不需要先发送一次OPTIONS请求,因此我们只要将访问设为简单请求就能达到目的

只要满足以下两种请求即为简单请求

(1) 请求方法是以下三种方法之一:
HEAD
GET
POST

(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

第一条很容易实现,关于第二条,我之前的请求是不符合的,因为我把token信息放到了HTTP的header中,再就是大家可能用的默认的Content-Type,默认是application/json,是不符合的

以下是我封装的网络请求接口

  • 需要校验是否登录的,先校验登录状态,未登录先去登录

  • 在url中添加access_token信息

  • 返回未登录错误401,跳转登录页面

  • 返回无权限错误403,跳转403页面

需要先安装Qs

npm install qs

网络请求

import authorize from './authorize'
import api from '../config/api'
import config from '../config/config'
import axios from 'axios'
import Qs from 'qs'
import router from '../../router'


function toLogin(redirect={go: -1}) {
  router.push({
    path: config.login_path,
    query:redirect
  })
}

function toForbidden() {
  router.push({
    path: config.forbidden_path
  })
}
/*
* check_login,请求数据之前,是否需要检查登录状态,如果登录已过期,则需要重新登录,然后再请求数据
*/
function get(url,data,check_login=false) {
  if(check_login&&!authorize.checkLogin()){
    //如果需要登录,且登录已经过期,则先进行登录,然后再进行数据处理
    return new Promise((resolve,reject)=>{
      toLogin()
      reject("登录过期,请先登录")
    })
  }

  return request(url,data,'get')
}

function post(url,data,check_login=false) {
  if(check_login&&!authorize.checkLogin()){
    //如果需要登录,且登录已经过期,则先进行登录,然后再进行数据处理
   return new Promise((resolve,reject)=>{
     toLogin()
     reject("登录过期,请先登录")
   })
  }

  return request(url,data,'post')
}

function request(url,data,method='get') {
  let params= method=='get'?data:'';
  let post_data= method=='post'?data:'';

  return new Promise((resolve,reject)=>{
    axios.request({
      url: api.baseUrl+url,
      method:method,
      params:{
        ...params,
        access_token:authorize.getToken()
      },
      data:post_data,

      transformRequest: [function (data) {
        return Qs.stringify(data);//把数据转化为QueryString
      }],

      headers:{
        'Content-Type':'application/x-www-form-urlencoded'
      },
      onUploadProgress:'',
      onDownloadProgress:''
    }).then((res)=>{
      res=res.data
      if(res.code=='1'){
        resolve(res.data)
      }else if(res.code=='401'){
        toLogin()
        reject("登录过期,请先登录")
      }else if(res.code=='403'){
        toForbidden()
        reject("缺少权限")
      }else if(res.code=='99'){
        reject(res.msg)
      }else {
        reject("未知code")
      }

    }).catch((err)=>{
      reject(err)
    })
  })

}

export default {
  get,post,toLogin
}

github地址:https://github.com/501351981/vue_yii_cms

分享到

点赞(4)