//通过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 复制代码
<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> 复制代码
//获得表单按钮元素 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 } 复制代码
// 获取key为age的第一个值 formdata.get("age"); // 获取key为age的所有值,返回值为数组类型 formdata.getAll("age"); 复制代码
//通过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"] 复制代码
key值不存在时,会自动添加相应的一条数据
//将存在的key为name的值修改为laoli formdata.set("name","laoli"); 复制代码
//判断是否包含key为name的数据 console.log(formdata.has("name"));//true //判断是否包含key为age的数据 console.log(formdata.has("age"));//false 复制代码
//删除key为name的值 formdata.delete("name"); console.log(formdata.get("name"));//null 复制代码
<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> 复制代码
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,请对比一下输出
axios.get('/data/json',{ params: { id: 12 } }).then(res => { console.log(res); }) 复制代码
status code: 304 not modified //请求到的数据与上次相同就会返回304 数据重定向
常用的data格式:
Content-Type:applicition/json //表示post方式以json格式发送 **Content-Type:multipart/from-data //表示post方式以formdata形式发送
post是新建 put与patch(只更新修改的)是更新
axios.delete('/delete',{ params:{id: 12} //query string parameters }).then() 复制代码
axios.delete('/delete',{ data:{id: 12} //request payload }).then() 复制代码
axios.all([ // 参数为一个数组 axios.get('/red'), axios.get('/blue') ]).then( axios.spread((redRes, blueRes) => { console.log(redRes,blueRes); }) ); 复制代码
let Axios = axios.create({ baseURL: 'http://127.0.0.1/read', timeout: 5000 }); 复制代码
// `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' }, 复制代码
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) } ); 复制代码
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'); 复制代码
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; 复制代码
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; 复制代码
欢迎大家留言评论