Javascript

FormData对象的作用及用法与Vue中axios的使用:

本文主要是介绍FormData对象的作用及用法与Vue中axios的使用:,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

FormData的主要用途

  1. 将form表单元素的name与value进行组合,实现表单数据的序列化,从而减少表单元素的拼接,提高工作效率。
  2. 异步上传文件

一、创建一个FormData对象

  1. 创建一个空对象:
//通过FormData构造函数创建一个空对象
var formdata=new FormData();
//可以通过append()方法来追加数据
formdata.append("name","laotie");
//通过get方法对值进行读取
console.log(formdata.get("name"));//laotie
//通过set方法对值进行设置
formdata.set("name","laoliu");
console.log(formdata.get("name"));//laoliu
复制代码
  1. 通过表单对FormData初始化
  • 创建表单:
<form id="advForm">
    <p>广告名称:<input type="text" name="advName"  value="xixi"></p>
    <p>广告类别:<select name="advType">
        <option value="1">轮播图</option>
        <option value="2">轮播图底部广告</option>
        <option value="3">热门回收广告</option>
        <option value="4">优品精选广告</option>
    </select></p>
    <p><input type="button" id="btn" value="添加"></p>
</form>
复制代码
  • 通过表单元素作为参数,实现对formData的初始化:
//获得表单按钮元素
var btn=document.querySelector("#btn");  //querySelector() 方法仅仅返回匹配指定选择器的第一个元素。
//为按钮添加点击事件
btn.onclick=function(){
    //根据ID获得页面当中的form表单元素
    var form=document.querySelector("#advForm");
    //将获得的表单元素作为参数,对formData进行初始化
    var **formdata** =new FormData(form);
    //通过get方法获得name为advName元素的value值
    console.log(formdata.get("advName"));//xixi
    //通过get方法获得name为advType元素的value值
    console.log(formdata.get("advType"));//1 
}
复制代码

二、操作方法

  1. 通过get(key)与getAll(key)来获取相对应的值
// 获取key为age的第一个值
formdata.get("age"); 
 // 获取key为age的所有值,返回值为数组类型
formdata.getAll("age");
复制代码
  1. 通过append(key,value)在数据末尾追加数据
//通过FormData构造函数创建一个空对象
var formdata=new FormData();
//通过append()方法在末尾追加key为name值为laoliu的数据
formdata.append("name","laoliu");
//通过append()方法在末尾追加key为name值为laoli的数据
formdata.append("name","laoli");
//通过append()方法在末尾追加key为name值为laotie的数据
formdata.append("name","laotie");

//通过get方法读取key为name的 第一个值
console.log(formdata.get("name"));//laoliu
//通过getAll方法读取key为name的所有值
console.log(formdata.getAll("name"));//["laoliu", "laoli", "laotie"]
复制代码
  1. 通过set(key, value)来设置修改数据

key值不存在时,会自动添加相应的一条数据

//将存在的key为name的值修改为laoli
formdata.set("name","laoli");
复制代码
  1. 通过has(key)来判断是否存在对应的key值
//判断是否包含key为name的数据
console.log(formdata.has("name"));//true
//判断是否包含key为age的数据
console.log(formdata.has("age"));//false
复制代码
  1. 通过delete(key)可以删除数据
//删除key为name的值
formdata.delete("name");
console.log(formdata.get("name"));//null
复制代码

三、通过XMLHttpRequest发送数据

  1. 创建表单:
<form id="advForm">
    <p>广告名称:<input type="text" name="advName" value="xixi"></p>
    <p>广告类别:<select name="advType">
        <option value="1">轮播图</option>
        <option value="2">轮播图底部广告</option>
        <option value="3">热门回收广告</option>
        <option value="4">优品精选广告</option>
    </select></p>
    <p>广告图片:<input type="file" name="advPic"></p>
    <p>广告地址:<input type="text" name="advUrl"></p>
    <p>广告排序:<input type="text" name="orderBy"></p>
    <p><input type="button" id="btn" value="添加"></p>
</form>
	
复制代码
  1. 发送数据:
var btn=document.querySelector("#btn");
btn.onclick=function(){
    var formdata=new FormData(document.getElementById("advForm"));
    var xhr=new XMLHttpRequest();
    xhr.open("post","http://127.0.0.1/adv");
    xhr.send(formdata);  // 上传文件
    xhr.onload=function(){ // 请求成功回调函数
        if(xhr.status==200){
            //...
        }
    }
}
复制代码

XMLHttpRequest知识详解 qs.stringify()将对象 序列化成URL的形式,以&进行拼接。

JSON是正常类型的JSON,请对比一下输出

Vue中axios的使用:

  1. get方法传递参数时需注意
axios.get('/data/json',{
	params: {
		id: 12
	}
}).then(res => {
	console.log(res);	
})
复制代码

status code: 304 not modified //请求到的数据与上次相同就会返回304 数据重定向

  1. post方法

常用的data格式:

  • form-data 用于表单提交,图标与文件上传
  • applicition/json

Content-Type:applicition/json //表示post方式以json格式发送 **Content-Type:multipart/from-data //表示post方式以formdata形式发送

post是新建 put与patch(只更新修改的)是更新

  1. delet方法
  • 接口需要在url上拼接参数
axios.delete('/delete',{
	params:{id: 12}     //query string parameters
}).then()
复制代码
  • 不是在url上进行传输的
axios.delete('/delete',{
	data:{id: 12}       //request payload
}).then() 
复制代码
  1. 并发请求(同时进行多个请求,并统一处理返回值) axios.all()与axios.spread()
axios.all([		//	参数为一个数组
  axios.get('/red'),
  axios.get('/blue')
]).then(		
  axios.spread((redRes, blueRes) => {
    console.log(redRes,blueRes);
  })
);
复制代码

二、axios配置

  1. 创建axios实例
let Axios = axios.create({
  baseURL: 'http://127.0.0.1/read',
  timeout: 5000
});
复制代码
  1. axios的配置参数(config)
// `url` 是用于请求的服务器 URL,为相对路径,会在前面拼接baseURL
  url: '/user',

  // `method` 是创建请求时使用的方法
  method: 'get', // default

  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: 'https://some-domain.com/api/',

// `headers` 是即将被发送的自定义请求头
  headers: {
	'X-Requested-With': 'XMLHttpRequest',
	'token': ''
  },

  // `params` 是即将与请求一起发送的 URL 参数
  // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
  params: {
    ID: 12345
  },

// `data` 是作为请求主体被发送的数据
  // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
  // 在没有设置 `transformRequest` 时,必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属:FormData, File, Blob
  // - Node 专属: Stream
  data: {
    firstName: 'Fred'
  },

复制代码
  1. axios的配置方法
  • 全局配置
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
复制代码
  • 实例配置
let instance = axios.create();
instance.defaults.timeout = 3000;
复制代码
  • 请求时配置
axios.get('/data.json', {
	timeout: 5000	
})
复制代码

三、拦截器

在请求或响应被处理前拦截它们

  • 请求拦截器
// 请求拦截器
axios.interceptors.request.use(
  config => {
    // 在发送请求前做些什么
    // config.headers  = {}  // 不可以直接这样在请求拦截器里设置headers  这样会把实例上定义的其他headers && defauls上的headers配置 全部覆盖
    config.headers.token = '' // 正确写法, headers里需要添加什么 再写什么
    
    return config;			//返回config
  },
  error => {
    // 在请求错误的时候做些什么
    return Promise.error(error);	//返回一个promise对象
  });
复制代码
  • 响应拦截器
axios.interceptors.response.use(
  res => {
    // 请求成功对响应数据做处理
    return res
  }, error => {
    // 响应错误做什么
    return Promise.reject(error)
  }
);
复制代码
  • 取消拦截器
let interceptors = axios.interceptors.request.use(
  config => {
    // 在发送请求前做些什么
    return config
  },
  error => {
    // 请求错误的时候做什么
    return Promise.reject(error)
  }
);
// 取消拦截器
axios.interceptors.request.eject(interceptors);
复制代码
  • 拦截器应用举例
// 移动端应用
let interceptors_phone = axios.create();
interceptors_phone.interceptors.request.use(
  config => {
    $('#modal').show();   // model 表示显示加载的内容前的 等待
    return config
  }
);
interceptors_phone.interceptors.response.use(
  res => {
    $('#model').hide();   // 数据响应后隐藏model
    return res
  }
);
复制代码
  • 统一的错误处理
// 实际开发中,一般添加统一的错误处理,不会在每次请求后进行.catch的错误处理
let interceptors = axios.interceptors.request.use(
  config => {
    // 在发送请求前做些什么
    return config
  },
  error => {
    // 请求错误的时候做什么 **********
	401 请求超时   404 not found
    return Promise.reject(error)
  }
);
复制代码
  • 取消正在进行的http请求
let source = axios.CancelToken.source();  // 生成一个source对象,里面有一个CancelToken

axios.get('user/login', {
  cancelToken: source.token
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
});
// 取消请求(message 可选)
source.cancel('cancel http');
复制代码

四、封装axios

  1. 封装api
const CONTACT_API = {
  // 获取联系人列表
  getContactList: {
    method: 'get',
    url: '/contactList'
  }
};
export default CONTACT_API;
复制代码

附上自己的封装

// api.js
const api = {
  login: {
    url: '/users/login',
    method: 'put'
  },
  getGroup: {
    url: '/group/all',
    method: 'get'
  }
};

export default api;




// request.js
import axios from 'axios';
import service from './api';
import {Toast} from 'vant';

import store from '../src/store/index';
import router from '../src/router/index';

// 根据环境配置
if (process.env.NODE_ENV === 'development') {
  axios.defaults.baseURL = 'http://127.0.0.1:3000';
} else if (process.env.NODE_ENV === 'production') {
  axios.defaults.baseURL = 'http://api.123dailu.com/';
}

// 请求超时时间
axios.defaults.timeout = 5000;

// 请求头设置
axios.defaults.headers.get['ANSWER_ACCESS_TOKEN'] = 'store.getters.token';

let instance = axios.create();

const Http = {};  // 包裹请求方法的容器
// 请求格式/参数的统一
for (let key in service) {
  let api = service[key];

  Http[key] = async function (
    params, // 请求参数  get: url  put,post,patch: data   delete: url
    isFormData = false, // 标识是否时form-data请求
    config = {}   // 配置参数
  ) {
    let url = api.url;
    let newParams = {};   // 用于form-data与json的转换
    // Content-type是否是form-data对象
    if (params && isFormData) {
      // 转换为把form-data
      newParams = new window.FormData();
      for (let i in params) {
        newParams.append(i, params[i])
      }
    } else {
      newParams = params
    }

    // 不同请求的判断
    let response = {};     // 盛放请求的返回值
    if (api.method === 'post' || api.method === 'put' || api.method === 'patch') {
      try {
        response = instance[api.method](url, newParams, config)
      } catch (err) {
        response = err;
      }
    } else if (api.method === 'delete' || api.method === 'get') {
      config.params = newParams;
      // 若参数需要放到data里,config.data
      try {
        response = await instance[api.method](url, config)
      } catch (err) {
        response = err;
      }
    }
    return response;  // 返回请求的响应值
  };
}



// 请求拦截器
instance.interceptors.request.use(
  config => {
    // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
    // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
    const token = store.getters.token;
    token && (config.headers.ANSWER_ACCESS_TOKEN = token);

    Toast.loading({
      mask: false,  // 是否有阴影
      duration: 0,  // 0为一直存在
      forbidClick: true, // 是否禁止点击
      message: '加载中...'
    });
    return config;
  },
  error => {
    Toast.clear();
    Toast('请求错误,请稍后重试');
  }
);

// 响应拦截器
instance.interceptors.response.use(
  res => {
    if (res.status === 200) {
      Toast.clear();
      return res.data;
    }
  },
  // 服务器状态码不是200的情况
  error => {
    console.log(error);
    Toast.clear();
    if (error.response.status) {
      switch (error.response.status) {
        // 401: 未登录
        // 未登录则跳转登录页面,并携带当前页面的路径
        // 在登录成功后返回当前页面,这一步需要在登录页操作。
        case 401:
          router.replace({
            path: '/login',
            query: {redirect: router.currentRoute.fullPath}
          });
          Toast('401: 未登录');
          break;
        // 403 token过期
        // 登录过期对用户进行提示
        // 清除本地token和清空vuex中token对象
        // 跳转登录页面
        case 403:
          Toast({
            message: '登录过期,请重新登录',
            duration: 1000,
            forbidClick: true
          });
          // 清除token
          localStorage.removeItem('token');
          store.commit('changeToken', null);
          // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
          setTimeout(() => {
            router.replace({
              path: '/login',
              query: {
                redirect: router.currentRoute.fullPath
              }
            });
          }, 1000);
          break;
        // 404请求不存在
        case 404:
          Toast({
            message: '网络请求不存在',
            duration: 1500,
            forbidClick: true
          });
          break;
        // 其他错误,直接抛出错误提示
        default:
          Toast({
            message: '404 请求错误,请稍后重试',
            duration: 1500,  // 0为一直存在
            forbidClick: true // 是否禁止点击
          });
      }
      return Promise.reject(error.response);
    }
  }
);

export default Http;

复制代码

分装 axios 更新

import axios from 'axios';
import server from './api';

// server 循环遍历输出不同的请求方法
let instance = axios.create({
  baseURL: 'http://localhost:8080',
  timeout: 3000
});

// 包裹循环遍历出的请求方法
const Http = {};

for (let key in server) {
  let api = server[key];   // url method

  Http[key] = async function (
      params,
      isFormData = false,
      config = {}
  ) {
    let url = api.url;
    let newParams = {};

    if (params && isFormData) {
      newParams = new FormData();
      for (let i  in params) {
        newParams.append(i, params[i])
      }
    } else {
      newParams = params;
    }
    let response;
    if (api.method === 'get' || api.method === 'put' || api.method === 'patch') {
      try {
        response = await instance[api.method](api.url, newParams, config);
      } catch (e) {
        console.log(e);
      }
    } else {
      try {
        response = await instance[api.method](api.url,config);
      } catch (e) {
        console.log(e);
      }
    }
    return response
  }
}

instance.interceptors.request.use(
    config => {
      if (store.state.token) {
        config.headers.token = `${store.state.token}`
      }
      return config
    }, err => {
      console.log(err);
    }
);

instance.interceptors.response.use(
    res => {
      return res
    }, err => {
      if (err.response) {
        switch (err.response.status) {
          case 401:
            /*
            * 返回401 表示前端的token 已经失效
            * 状态码 前后端统一
            * 清楚vuex 种的token
            */
        }
      }
      return Promise.reject(err)
    }
);

export default Http;


复制代码

欢迎大家留言评论

这篇关于FormData对象的作用及用法与Vue中axios的使用:的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!