vue cli3 项目中如何使用axios发送post请求

目录
  • 使用axios发送post请求
    • 首先需要安装对应的第三方包
    • 发送post请求
    • 发送get请求将index.js中再添加如下代码
  • vue使用axios的踩坑记录
    • axios跨域
    • 解决方法
    • axios发起post请求后端无法接收数据

使用axios发送post请求

react  同样适用

首先需要安装对应的第三方包

  • cnpm  i  -S axios
  • cnpm  i  -S lodash

然后在做下边的

在vue 项目中创建一个这样的文件目录

发送post请求

index.js中的文件内容是:

import axios from "axios"
import _ from "lodash"

// 处理请求参数
const coverFormData = (obj) => {
	let data = Object.keys(obj.data).map(item => {
		let value = obj.data[item];
		if(_.isArray(value) || _.isObject(value)){
			value = JSON.stringify(value)
		}
		return encodeURIComponent(item) + '=' + encodeURIComponent(value);
	}).join('&');

	return {data: data, url: obj.url};
}

function post(obj) {
	const { data, url } = coverFormData(obj);
	return new Promise((resolve, reject) => {
		axios.post(url,  data)
			.then(res => {
				// obj.success ? obj.success(res) : null
				resolve(res.data);
			})
			.catch(error => {
				// obj.error ? obj.error(error) : null;
				reject(error);
			})
	})

}

let requests = {}
requests.post = post

export default requests

使用:

效果:

发送get请求将index.js中再添加如下代码

requests.get = obj => {
	const { data, url } = coverFormData(obj);
	return new Promise((resolve, reject) => {
		axios.get(url + '?' + data).then(res => {
			obj.success ? obj.success(res) : null;
			resolve(res.data);
		}).catch(error => {
			obj.error ? obj.error(error) : null;
			reject(error);
		})
	})
}

使用和post的一模一样只是将requests.post改成request.get

vue使用axios的踩坑记录

axios跨域

在自己写的一个项目中,想要直接将学号和密码发到学校的教务系统,结果跨域了。。。。。。

原代码

// url为要访问的域名
axios.get(`${url}?method=authUser&xh=${this.sNo}&pwd=${this.password}`)
.then((res) => {
    // ...
}).catch((err) => {
	// ...
})

在网上找解决跨域的问题时,看到很多都是修改config下的…文件,但是vue-cli脚手架创建的vue3项目中并没有config文件夹,所以直接去到官方文档查找配置

解决方法

在package.json同级文件夹下创建vue.config.js,配置如下

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'url', //设置要访问的域名和端口号
                changeOrigin: true, //设置为跨域
                pathRewrite: {
                    '^/api': '/' //这里理解成用‘/api'代替target里面的地址,在后面发起请求时,/api就会代替target中的值,可以实现跨域
                }
            }
        }
    }
}

修改我们的请求代码

axios.get(`/api/app.do?method=authUser&xh=${this.sNo}&pwd=${this.password}`)
            .then((res) => {
                // ...
            }).catch((err) => {
				// ...
            })

这里使用/api替换了原来的url,实现跨域

axios发起post请求后端无法接收数据

在第一次使用axios向后台发送post请求时,发现自己发送的数据后端没有接收到,后端用的是spring框架,但是同样的请求我使用自己的node服务器测试时却好好的

原代码

axios.post(url,{data:data})
  .then(res => {
      // ...
  }).catch(err => {
      // ...
  })

我用node服务器打印请求发过拉的数据,都能得到{"data":1},但是后端那里总是只能得到null

在查看前后端代码后总是觉得没问题,唯一的变数只有axios了,所以去到淘宝镜像上看axios的使用,看到特性里面的概述

大概就是说可以对请求中的数据和响应的数据做格式转换,而且会自动对json数据做转换,我尝试将上面的请求改成使用非json格式传输

axios.post(url,`data=${data}`)
  .then(res => {
      // ...
  }).catch(err => {
      // ...
  })

意料之中的成功了,那么为什么呢,在查阅资料后,终于在GitHub上找到了对应的源码

transformRequest: [function transformRequest(data, headers) {
	    normalizeHeaderName(headers, 'Accept');
	    normalizeHeaderName(headers, 'Content-Type');
	    if (utils.isFormData(data) ||
	      utils.isArrayBuffer(data) ||
	      utils.isBuffer(data) ||
	      utils.isStream(data) ||
	      utils.isFile(data) ||
	      utils.isBlob(data)
	    ) {
	      return data;
	    }
	    if (utils.isArrayBufferView(data)) {
	      return data.buffer;
	    }
	    if (utils.isURLSearchParams(data)) {
	      setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
	      return data.toString();
	    }
	    // 看这里------------------------------------------
	    if (utils.isObject(data)) {
	      setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
	      return JSON.stringify(data);
	    }
	    return data;
	  }]

当判断为对象时,会把headers设置为application/json;charset=utf-8,也就是Content-Type,而根据项目组里的后端同学所说的,服务端要求的是Content-Type': 'application/x-www-form-urlencoded,我试着在发送请求前将headers设置为application/x-www-form-urlencoded,结果还是不行,大概是因为源码中对headers的修改在自己的设置之后实现的,但是这样写的话,要写出一串很长的字符串,感觉挺麻烦的,那就可以尝试下面的方法

因为源码中是通过transformRequest来修改headers的,而这个方法我们其实也可以自己实现,所以我们只要在发送请求的时候自己来实现这个方法就可以了,这里通过修改data的数据结构来达到目的

import Qs from 'qs'
axios({
	url:url,
	data:{
		data:data
	},
	transformRequest: [function (data) {
	    // 对data的数据格式进行修改
	    return Qs.stringify(data)
    }],
	headers: {
		'deviceCode': 'A95ZEF1-47B5-AC90BF3'
	})
	 .then(res => {
      // ...
  }).catch(err => {
      // ...
  })

上面是将data的数据格式进行转换,但是我们也可以选择修改处理data的方式

axios({
	url:url,
	data:{
		data:data
	},
	transformRequest: [function transformRequest(data, headers) {
	    normalizeHeaderName(headers, 'Accept');
	    normalizeHeaderName(headers, 'Content-Type');
	    if (utils.isFormData(data) ||
	      utils.isArrayBuffer(data) ||
	      utils.isBuffer(data) ||
	      utils.isStream(data) ||
	      utils.isFile(data) ||
	      utils.isBlob(data)
	    ) {
	      return data;
	    }
	    if (utils.isArrayBufferView(data)) {
	      return data.buffer;
	    }
	    if (utils.isURLSearchParams(data)) {
	      setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
	      return data.toString();
	    }
	    // 看这里------------------------------------------
	    if (utils.isObject(data)) {
	      setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
	      let _data = Object.keys(data)
	      return encodeURI(_data.map(name => `${name}=${data[name]}`).join('&'));
	    }
	    return data;
	  }])
	 .then(res => {
      // ...
  }).catch(err => {
      // ...
  })

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • VUE axios发送跨域请求需要注意的问题

    在实际项目中前端使用到vue,后端使用php进行开发.前端使用axios请求请求 关于跨域 跨域的概念这些就不说了,百度一大堆相关的资料信息.我就只在这里记录下我在使用当中遇到的问题,以纪念在逝去的几个小时中资料查找的艰辛. 不多说,直接上代码~~~~ 同理,跨域的解决方案为cros.服务器 PHP端代码如下(laravel 中间件进行处理): public function handle($request, Closure $next) { if ($request->isMethod('OP

  • vue项目中axios使用详解

    axios在项目中(vue)的使用 没有vue项目的使用vue-cli脚手架生成一个webpack模板的项目即可愉快的看下去了~ 如果开发遇到跨域问题可以参考:http://www.jb51.net/article/134571.htm 安装axios到项目中 npm install axios --save 配置wepack别名,不同环境访问不同的配置接口 配置: 使用:import config from 'config' 封装一个axios实例 新建fetch.js,在此创建axios实例

  • 详解vue中axios请求的封装

    axios Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中, 也是vue官方推荐使用的http库:封装axios,一方面为了以后维护方便,另一方面也可以对请求进行自定义处理 安装 npm i axios 封装 我把axios请求封装在http.js中,重新把get请求,post请求封装了一次 首先,引入axios import axios from 'axios' 设置接口请求前缀 一般我们开发都会有开发.测试.生产环境,前缀需要加以区分,我们利用

  • vue-cli axios请求方式及跨域处理问题

    vue-cli axios请求方式以及跨域处理 安装axios cnpm install axios --save 在要使用axios的文件中引入axios main.js文件 :import axios from 'axois' 要发送请求的文件:import axios from 'axois' 在config/index.js文件设置代理 dev: { proxyTable: {// 输入/api 让其去访问http://localhost:3000/api '/api':{ target

  • vue cli3 项目中如何使用axios发送post请求

    目录 使用axios发送post请求 首先需要安装对应的第三方包 发送post请求 发送get请求将index.js中再添加如下代码 vue使用axios的踩坑记录 axios跨域 解决方法 axios发起post请求后端无法接收数据 使用axios发送post请求 react  同样适用 首先需要安装对应的第三方包 cnpm  i  -S axios cnpm  i  -S lodash 然后在做下边的 在vue 项目中创建一个这样的文件目录 发送post请求 index.js中的文件内容是:

  • Vue项目中如何使用Axios封装http请求详解

    前言 使用axios可以统一做请求响应拦截,例如请求响应时我们拦截响应信息,判断状态码,从而弹出报错信息.请求超时的时候断开请求,还可以很方便地使用then或者catch来处理请求. 下载源码 安装 npm install axios --save 建立http.js文件 在/src/utils/目录下建立一个htttp.js 1.首先导入axios和router. import axios from 'axios'; import router from '../router'; 2.接着设置

  • 在vue项目中使用axios发送post请求出现400错误的解决

    目录 使用axios发送post请求出现400错误 出现400状态码主要有两种原因 总结了错误的几个原因 vue axios400 Bad Request问题 使用axios发送post请求出现400错误 出现400状态码主要有两种原因 1.bad request:“错误的请求" 2.invalid hostname:"不存在的域名” 我报的错是第一种bad request 总结了错误的几个原因 1.请求头错误,前端请求头的content-type和后端不一致 axios默认的请求头的

  • Vue项目中如何封装axios(统一管理http请求)

    1.需求说明 在使用Vue.js框架开发前端项目时,会经常发送ajax请求服务端接口,在开发过程中,需要对axios进一步封装,方便在项目中的使用. 2.Vue项目结构 在本地创建Vue项目,目录结构如下: - public  静态资源文件  - src  |- assets  静态资源目录  |- components 公共组件目录  |- http   axios封装目录  |- router  路由管理目录  |- store  状态管理目录  |- views  视图组件目录  |- A

  • 解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题

    vue +webpack 项目中数据更新后页面没有刷新问题,ie11下,如果GET请求请求相同的URL,默认会使用之前请求来的缓存数据,而不会去请求接口获取最新数据,我用的解决方法是在每个请求发送前,拦截请求并给请求接口的URL后加一个时间戳(new Date().getTime()),这样就保证了每一次请求的URL都不同,ie11就会不断的请求接口而不使用缓存数据. 代码如下 if(config.url.indexOf('?')>-1){ config.url = url + config.u

  • Vue CLI3.0中使用jQuery和Bootstrap的方法

    Vue 中使用 jQuery 和 Bootstrap 不是特别符合 Vue 原生的写法,但是有时候又要用,所以放上我的引入设置,供大家参考. 在 Vue CLI2.0 中引入 jQuery 和 Bootstrap 需要设置很多配置项,网上有很多方法法,这里不重复写了.直接上 Vue CLI3.0 配置步骤. 第一步:安装 jQuery. Bootstrap.popper.js依赖. 其中popper.js 用于在 Bootstrap 中显示弹窗.提示.下拉菜单,所以需要引入. npm insta

  • vue管理系统项目中的一些核心技能汇总

    目录 前言 1. Axios 拦截器和二次封装 1.1 Axios 请求和响应拦截器. 1.2 Axios 二次封装 2. Vuex 的数据持久化 3. 路由守卫和动态路由的挂载 3.1 路由守卫 3.2 动态路由的挂载 4. 环境变量的配置文件 5. 封装一个按钮级权限的自定义指令 总结 前言 很多脚手架搭建的 vue 的管理系统项目,其核心模块的处理方式大致上都是一样的. 所以,我结合之前项目,整理了一下重要模块的解决方案. 1. Axios 拦截器和二次封装 1.1 Axios 请求和响应

  • 详解vue在项目中使用百度地图

    第一步,去百度地图开发者申请秘钥. 第二步在项目中引入,具体如下 其中index.html存放地图链接,代码如下 然后在APP.vue里面实现,代码如下 <template> <div id="app"> <div id="allmap" ref="allmap"></div> <router-view></router-view> </div> </tem

  • vue+element项目中过滤输入框特殊字符小结

    可以在main.js中写入方法 Vue.prototype.validSe = function (value, number = 255) { value = value.replace(/[`-*~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]·~!@#¥%--&*()--\-+={}|<>?:""[].:'',..]/g, '').replace(/\s/g, ""); if (value.

  • Vue.js项目中管理每个页面的头部标签的两种方法

    在 Vue SPA 应用中,如果想要修改 HTML 的头部标签,如页面的 title ,我们只能去修改 index.html 模板文件,但是这个是全局的修改,如何为每个页面都设置不一样的 title 呢?下面介绍两种方法. 使用router.meta 在路由里面配置每个路由的地址: routes: [ { /* (首页)默认路由地址 */ path: '/', name: 'Entrance', component: Entrance, meta: { title: '首页入口' } }, {

随机推荐