笔记_axios提交form data

本文介绍如何使用Axios结合qs库解决前端向后端提交FormData格式数据的问题,通过配置请求头和序列化参数,确保后端能正确解析数据。

axios默认将数据提交至后端InputStream中,由于历史遗留问题,部分接口使用取form 中的数据,导致前端提交后端获取不到,直接用AJAX可以解决这个问题,但一个页面中两种方式emmmm。。。 。。。  所以有了下面的故事。。。 。。。

1、配置请求头信息

{  headers: {'Content-Type':'application/x-www-form-urlencoded'}  }

参数若默认为js对象会被序列化为js字符串,提交到后端数据是在form中但格式不对无法解析

2、引入qs

npm i qs

3、参数序列化

Qs.stringify(args)

完整样例:

axios.post(url, Qs.stringify(args), {
      headers: {'Content-Type':'application/x-www-form-urlencoded'}     
}).then(callbak).catch((err) => {
      layerPage.complete();
      window_alert(err.message);
});

 

其实ajxa更方便,各人喜好吧

$.ajax({
    url: url,
    data: args,
    type: "POST",
    cache: false,
    success: callbak,
    error: (err) => {
        window_alert(err);
    }
});

axios,发送网络请求 在vue项目中安装axios,命令行输入(npm install axios)/npm install axios vue-axios 注册axios对象,只需要注册一次 创建axios目录,创建js文件,配置axios,导入vue、axios和vue-axio,通过use加载到vue中 例: // axios整合到vue中,方便以后在组件中就可以直接使用 import Vue from 'vue' import axios from 'axios' import VueAxios from 'vue-axios' // axios加载到vue中,加载axios模块 Vue.use(axios,VueAxios) 在main.js中引入js文件,挂载到vue对象中 例: //引入js脚本 import axios from './axios/index.js' 例: new Vue({ //挂载 axios }) 使用 Vue.axios.请求方式 Vue.axios.请求方式 请求方式,axios支持链式语法 this.axios.get(地址); this.axios.post(地址); this.axios.put(地址); this.axios.delete(地址); 子主题 5 this.axios() 语法: this.axios({ }) 属性 url:请求的地址 method:请求的方式 baseURL,可定义请求地址,和参数相加即可 reponseType:返回的格式 data:向主体发送的参数 子主题 6 子主题 7 Vue.$http.请求方式 注意: data和params的区别,data传递的为参数,?参数=值&参数=值,而params传递的参数为/参数=值/参数=值/参数=值 params传值 直接在axios中定义params属性,里面为键值对的形式,请求时会在地址后拼接属性 例: this.axios({ url : baseURL, method : 'GET', reponseType : 'json', params:{ nname : '1', cid : '3' } }).then(function(re){ console.log(re.data); }) data传值 请求为POST时,data中的值就无法传入后端,因为axios默认传值的数据格式为Request Payload,不是我们常用的Form Dataaxios默认将值作为json形式发送,我们要以键值对的形式进行发送,当格式为Request Payload,不会读取请求体中的数据和相应的参数处理 Request Payload参数为json格式 例:{id:1,name:1} Form Data,以&符拼接 例:id=1&name=1 解决的方式 创建URLSearchParams参数处理对象,用于返回新的URLSearchParams对象,将添加的键值对转为一个url参数的字符串 var data2 = new URLSearchParams(); data2.append("nname","1"); data2.append("cid","3"); this.axios.post(baseURL,data2).then(function(re){ console.log(re.data) }) 创建FormData对象,通过append()追加数据,将键值对进行组合 FormData主要用于表单元素的name和value进行组合,以及异步上传文件 使用 var data3 = new FormData(); data3.append("nname","w"); data3.append("cid","3"); this.axios.post(baseURL,data3).then(function(re){ console.log(re.data) }) 使用qs插件将对象序列化form data 安装qs插件 main.js中导入qs,然后安装qs import qs from 'qs' Vue.use(qs) 所用组件中导入qs import qs from 'qs' 使用qs将对象序列化为一个url地址参数的字符串 var params = { nname : '1', cid : '3' } var data = qs.stringify(params); 请求 this.axios.post(baseURL,data).then(function(re){ console.log(re.data) }) 修改请求头的Content-Type方式 在axios中加入 headers:{ "Content-Type":"application/x-www-form-urlencoded" } transformRequest允许在请求之前修改请求数据,只能用在PUT、POST和PATCH请求的方式 this.axios({ url : baseURL, method : 'POST', reponseType : 'json', headers:{ "Content-Type":"application/x-www-form-urlencoded" }, data:{ "nname":"w", "cid":"3" }, transformRequest:[function(data){ var n = new FormData(); n.append("nname","1"); n.append("cid","3"); return n; }] }).then(function(re){ console.log(re.data); }) 状态码 1开头 2开头,证明请求成功 3开头,重定向问题 4开头,客户端错误 5开头,服务台报错 子主题 3 子主题 4 子主题 5 子主题 5 子主题 4 子主题 5 这是我的笔记内容我需要重新学习Vue的axios请求,你给我写一个例子要求基于脚手架来做,涉及多个层面,比如请求方式的封装,前置和后置拦截器,多请求的编写语法注意
09-27
<think>我们基于Vue脚手架创建一个项目,然后集成axios,并实现以下功能: 1. 封装axios实例,设置基础URL和超时时间 2. 添加请求拦截器(前置)和响应拦截器(后置) 3. 封装GET、POST、PUT、DELETE等请求方法 4. 编写多个请求的示例(例如并发请求) 步骤: 1. 创建Vue项目(如果已有可跳过) 2. 安装axios 3. 创建axios实例并封装 4. 在组件中使用封装的请求方法 详细步骤: ### 1. 创建Vue项目 ```bash vue create axios-interceptors-demo cd axios-interceptors-demo ``` ### 2. 安装axios ```bash npm install axios ``` ### 3. 封装axios 在`src`目录下创建`utils/request.js`文件: ```javascript import axios from 'axios' // 创建axios实例 const service = axios.create({ baseURL: 'https://jsonplaceholder.typicode.com', // 设置基础URL timeout: 5000, // 请求超时时间 }) // 请求拦截器(前置) service.interceptors.request.use( (config) => { // 在发送请求之前可以做些什么,例如设置token // config.headers.Authorization = 'Bearer token' console.log('请求拦截器:', config) return config }, (error) => { // 对请求错误做些什么 console.log('请求拦截器错误:', error) return Promise.reject(error) } ) // 响应拦截器(后置) service.interceptors.response.use( (response) => { // 对响应数据做点什么,例如只返回data部分 console.log('响应拦截器:', response) return response.data }, (error) => { // 对响应错误做点什么 console.log('响应拦截器错误:', error) return Promise.reject(error) } ) // 封装GET请求 export const get = (url, params) => { return service.get(url, { params }) } // 封装POST请求 export const post = (url, data) => { return service.post(url, data) } // 封装PUT请求 export const put = (url, data) => { return service.put(url, data) } // 封装DELETE请求 export const del = (url) => { return service.delete(url) } // 并发请求 export const all = (requests) => { return axios.all(requests) } export default service ``` ### 4. 在组件中使用 在`src/views`下创建`AxiosDemo.vue`组件: ```vue <template> <div> <h1>Axios封装示例</h1> <button @click="handleGet">GET请求</button> <button @click="handlePost">POST请求</button> <button @click="handlePut">PUT请求</button> <button @click="handleDelete">DELETE请求</button> <button @click="handleConcurrent">并发请求</button> <pre>{{ responseData }}</pre> </div> </template> <script> import { get, post, put, del, all } from '@/utils/request' export default { data() { return { responseData: null } }, methods: { async handleGet() { try { const data = await get('/posts/1') this.responseData = data } catch (error) { console.error('GET请求错误:', error) } }, async handlePost() { try { const data = await post('/posts', { title: 'foo', body: 'bar', userId: 1 }) this.responseData = data } catch (error) { console.error('POST请求错误:', error) } }, async handlePut() { try { const data = await put('/posts/1', { id: 1, title: 'updated title', body: 'updated body', userId: 1 }) this.responseData = data } catch (error) { console.error('PUT请求错误:', error) } }, async handleDelete() { try { const data = await del('/posts/1') this.responseData = data } catch (error) { console.error('DELETE请求错误:', error) } }, async handleConcurrent() { try { const requests = [ get('/posts/1'), get('/posts/2') ] const responses = await all(requests) // responses是数组,每个元素是每个请求的结果 this.responseData = responses } catch (error) { console.error('并发请求错误:', error) } } } } </script> ``` ### 5. 添加路由(如果需要) 在`src/router/index.js`中: ```javascript import Vue from 'vue' import VueRouter from 'vue-router' import AxiosDemo from '../views/AxiosDemo.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'AxiosDemo', component: AxiosDemo } ] const router = new VueRouter({ mode: 'history', routes }) export default router ``` ### 6. 修改App.vue ```vue <template> <div id="app"> <router-view/> </div> </template> ``` ### 7. 运行 ```bash npm run serve ``` ### 代码说明 1. **请求封装**:我们将axios实例化,并封装了get、post、put、delete方法,以及并发请求的all方法。 2. **拦截器**: - 请求拦截器:在请求发出前统一处理(例如添加token)。 - 响应拦截器:在响应后统一处理(例如提取data,或处理错误)。 3. **多请求**:使用`axios.all`处理并发请求。 这样,我们就实现了一个基于Vue脚手架、包含请求封装、拦截器和多请求的axios示例。 ### 相关问题 1. 如何在请求拦截器中添加认证token? 2. 响应拦截器中如何处理不同的错误状态码? 3. 如何取消axios请求? 4. axios的并发请求和顺序请求有什么区别? </think>以下是一个基于 Vue 脚手架的 Axios 请求封装示例,包含请求方式封装、拦截器实现和多请求处理: ### 完整实现方案 #### 1. 安装依赖 ```bash npm install axios ``` #### 2. 封装 Axios 请求 (src/utils/request.js) ```javascript import axios from 'axios' // 创建实例 const service = axios.create({ baseURL: 'https://jsonplaceholder.typicode.com', timeout: 10000 }) // 请求拦截器(前置处理) service.interceptors.request.use( config => { console.log('[请求拦截]', config.url) // 示例:添加认证令牌 const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } // 示例:修改请求数据格式 if (config.method === 'post') { config.headers['Content-Type'] = 'application/json' } return config }, error => { console.error('请求拦截出错:', error) return Promise.reject(error) } ) // 响应拦截器(后置处理) service.interceptors.response.use( response => { console.log('[响应拦截]', response.config.url) // 统一处理响应格式 return response.data }, error => { console.error('响应拦截出错:', error) // 统一错误处理 if (error.response) { switch (error.response.status) { case 401: console.error('未授权,请重新登录') break case 403: console.error('拒绝访问') break case 500: console.error('服务器错误') break default: console.error('未知错误') } } return Promise.reject(error) } ) // 封装请求方法 const request = { get(url, params) { return service.get(url, { params }) }, post(url, data) { return service.post(url, data) }, put(url, data) { return service.put(url, data) }, delete(url) { return service.delete(url) }, // 并发请求 all(requests) { return axios.all(requests) } } export default request ``` #### 3. 使用示例 (src/views/AxiosDemo.vue) ```vue <template> <div> <h1>Axios 请求演示</h1> <button @click="getData">GET 请求</button> <button @click="postData">POST 请求</button> <button @click="putData">PUT 请求</button> <button @click="deleteData">DELETE 请求</button> <button @click="concurrentRequests">并发请求</button> <div v-if="loading">加载中...</div> <pre v-else-if="responseData">{{ responseData }}</pre> <div v-if="error">{{ error }}</div> </div> </template> <script> import request from '@/utils/request' export default { data() { return { loading: false, responseData: null, error: null } }, methods: { async getData() { try { this.loading = true this.responseData = await request.get('/posts/1') } catch (err) { this.handleError(err) } finally { this.loading = false } }, async postData() { try { this.loading = true const data = { title: 'foo', body: 'bar', userId: 1 } this.responseData = await request.post('/posts', data) } catch (err) { this.handleError(err) } finally { this.loading = false } }, async putData() { try { this.loading = true const data = { id: 1, title: 'updated title', body: 'updated body', userId: 1 } this.responseData = await request.put('/posts/1', data) } catch (err) { this.handleError(err) } finally { this.loading = false } }, async deleteData() { try { this.loading = true this.responseData = await request.delete('/posts/1') } catch (err) { this.handleError(err) } finally { this.loading = false } }, async concurrentRequests() { try { this.loading = true // 多个并发请求 const results = await request.all([ request.get('/posts/1'), request.get('/posts/2'), request.get('/users/1') ]) this.responseData = { post1: results[0], post2: results[1], user1: results[2] } } catch (err) { this.handleError(err) } finally { this.loading = false } }, handleError(error) { this.error = `请求失败: ${error.message}` console.error('API 错误:', error) } } } </script> ``` ### 核心功能说明 #### 1. 请求方式封装 - **四种基本请求方法**:GET/POST/PUT/DELETE - **统一入口**:所有请求通过`request`对象的方法调用 - **参数处理**:GET请求使用`params`,POST/PUT使用`data` #### 2. 拦截器实现 1. **请求拦截器**: - 添加认证令牌(Authorization Header) - 设置内容类型(Content-Type) - 记录请求日志 2. **响应拦截器**: - 提取核心数据(`response.data`) - 统一错误处理(HTTP状态码处理) - 异常日志记录 #### 3. 多请求处理 - 使用 `axios.all()` 实现并发请求 - 通过数组接收多个请求结果 - 结构化组织响应数据 #### 4. 组件使用规范 - 统一加载状态管理(loading) - 错误处理标准化(handleError) - 响应数据展示(模板渲染) ### 配置路由器 (src/router/index.js) ```javascript import Vue from 'vue' import Router from 'vue-router' import AxiosDemo from '@/views/AxiosDemo' Vue.use(Router) export default new Router({ routes: [ { path: '/axios-demo', name: 'AxiosDemo', component: AxiosDemo } ] }) ``` ### 最佳实践建议 1. **环境配置**:在`.env`文件中管理不同环境的API地址 ```env:.env.development VUE_APP_API_BASE_URL = https://dev-api.example.com ``` ```javascript:request.js baseURL: process.env.VUE_APP_API_BASE_URL ``` 2. **取消请求**:添加请求取消功能 ```javascript // 创建CancelToken源 const source = axios.CancelToken.source() // 在请求中配置 request.get('/posts', { cancelToken: source.token }) // 取消请求 source.cancel('Operation canceled by user') ``` 3. **重试机制**:添加请求失败自动重试 ```javascript service.interceptors.response.use(null, (error) => { const config = error.config if (!config || !config.retry) return Promise.reject(error) config.retryCount = config.retryCount || 0 if (config.retryCount >= config.retry) return Promise.reject(error) config.retryCount += 1 return new Promise(resolve => { setTimeout(() => resolve(service(config)), config.retryDelay || 1000) }) }) ``` 此实现方案提供了企业级的 Axios 封装模式,可直接用于实际项目开发,具有良好的扩展性和可维护性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值