Vue 使用axios 发送post请求,参数格式有错误问题

本文探讨了在Vue中使用Axios发送POST请求时遇到的参数格式问题,详细介绍了如何通过引入QS库并设置Content-Type来正确序列化参数,避免了常见的无法present错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自https://blog.csdn.net/nihaoqiulinhe/article/details/79084755
推荐去看原文,我转的原因是怕自己找不到了,23333

Vue 使用axios 发送post请求,参数格式有错误问题:

注:网上很多都是使用post发送的例子,但是我使用过程当中,就是参数有问题,一直报参数无法present的问题,后来看到这篇博客,需要引入QS对参数进行转换,且要设置Content-Type,这样就可以了,特别注意QS的功能:

  
  1. 完全不是一个东西,功能虽然都是序列化。假设我要提交的数据如下
  2. var a = {name:'hehe',age:10};
  3. qs.stringify序列化结果如下
  4. name=hehe&age=10
  5. 而JSON.stringify序列化结果如下:
  6. "{"a":"hehe","age":10}"
第二个坑:使用axios的then之后,要给data赋值,使用this报错,以下是原因和解决方案:

  
  1. 在then 这个里边的赋值方法this.followed = response.data.followed会出现报错,什么原因呢?在Google上查了下,原来是在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定。
  2. 可以看下 Stackoverflow 的解释:
  3. In option functions like data and created, vue binds this to the view-model instance for us, so we can use this.followed, but in the function inside then, this is not bound.
  4. So you need to preserve the view-model like (created means the component's data structure is assembled, which is enough here, mounted will delay the operation more):
  5. 解决方法:
  6. created() {
  7. var self = this;
  8. axios.post('/api/question/follower', {
  9. 'question':this.question,
  10. 'user':this.user
  11. }).then(function(response){
  12. // console.log(response.data);
  13. self.followed = response.data.followed;
  14. })
  15. },
  16. 或者我们可以使用 ES6 的 箭头函数arrow function,箭头方法可以和父方法共享变量 :
  17. created() {
  18. axios.post('/api/question/follower', {
  19. 'question':this.question,
  20. 'user':this.user
  21. }).then((response) => {
  22. this.followed = response.data.followed;
  23. })
  24. },




以下是转载的内容:

在半年前尤大就不推荐使用vue-resource了,好像我这么没安全感的人,没人维护的东西不敢碰。

1987062-b3255d564903d3d7.png

那么axios这个是什么呢?是一个国外友人开发的基于Promise 用于浏览器和 nodejs 的 HTTP 客户端。它有什么用法呢:

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 发出 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防止 [CSRF/XSRF](http://baike.baidu.com/link?*url=iUceAfgyfJOacUtjPgT4ifaSOxDULAc_MzcLEOTySflAn5iLlHfMGsZMtthBm5sK4y6skrSvJ1HOO2qKtV1ej_)

作者这造型一看就是大牛,以后有机会我也要搞一个,浪。


Paste_Image.png

反正功能很多啦,用法一搜一大堆。
英文:点这里看看官网教程

axios安装


  
  1. $ npm install axios

如果不用npm,可以通过cdn引入

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

  

axios基本用法

这里笔者使用的是es6,由于标题是要结合vue,因此将vue、axios以及vue-axios引入。


  
  1. import Vue from 'vue'
  2. import axios from 'axios'
  3. import VueAxios from 'vue-axios'
  4. #通过use方法加载axios插件
  5. Vue.use(VueAxios,axios)

看看有哪些用法:


  
  1. axios.request(config)
  2. axios.get(url[, config])
  3. axios.delete(url[, config])
  4. axios.head(url[, config])
  5. axios.post(url[, data[, config]])
  6. axios.put(url[, data[, config]])
  7. axios.patch(url[, data[, config]])

就挑我们最熟悉的get和post来看看:

GET用法

.vue模板:


  
  1. var vm = this
  2. this.$http.get(vm.testUrl).then((response)=>{
  3. alert(response.data.msg);
  4. })

这里我们通过this.$http去调用axios,如果之前你的vue-resourse也是这么写的话,那简直可以无缝切换。当然你你换成this.axios也是没有问题的,但扩展性就不好了。

testUrl:


  
  1. public function test(){
  2. return json(array('status'=>1,'msg'=>'success'));
  3. }

现象:


Paste_Image.png

POST用法

这个post要重点说下,有坑。
.vue模板:


  
  1. var vm = this
  2. this.$http.post(vm.testUrl,{"name":"痞子达"})
  3. .then((response)=>{
  4. alert(response.data.msg);
  5. })

testUrl:


  
  1. public function test(){
  2. return json(array('statys'=>1,'msg'=>$_POST['name']));
  3. }

正常应该弹出“痞子达”,但是并没有,还报了500错误。
接口提示未定义数组索引: name

Paste_Image.png

抓包看了看,是以Request Payload的形式传送了参数。
不是我们熟悉的form-data形式,看看api:


  
  1. axios.post(url[, data[, config]])

第三个参数是config配置,这个配置应该可以做点事儿。这个config的参数有很多,先看看(随便瞅下就行):

  • url —— 用来向服务器发送请求的url
  • method —— 请求方法,默认是GET方法
  • baseURL —— 基础URL路径,假如url不是绝对路径,如https://some-domain.com/api/v1/login?name=jack,那么向服务器发送请求的URL将会是baseURL + url。
  • transformRequest —— transformRequest方法允许在请求发送到服务器之前修改该请求,此方法只适用于PUT、POST和PATCH方法中。而且,此方法最后必须返回一个string、ArrayBuffer或者Stream。
  • transformResponse —— transformResponse方法允许在数据传递到then/catch之前修改response数据。此方法最后也要返回数据。
    headers —— 发送自定义Headers头文件,头文件中包含了http请求的各种信息。
  • params —— params是发送请求的查询参数对象,对象中的数据会被拼接成url?param1=value1&param2=value2。
  • paramsSerializer —— params参数序列化器。
  • data —— data是在发送POST、PUT或者PATCH请求的数据对象。
  • timeout —— 请求超时设置,单位为毫秒
  • withCredentials —— 表明是否有跨域请求需要用到证书
  • adapter —— adapter允许用户处理更易于测试的请求。返回一个Promise和一个有效的response
  • auth —— auth表明提供凭证用于完成http的身份验证。这将会在headers中设置一个Authorization授权信息。自定义Authorization授权要设置在headers中。
  • responseType —— 表示服务器将返回响应的数据类型,有arraybuffer、blob、document、json、text、stream这6个类型,默认是json类似数据。
  • xsrfCookieName —— 用作 xsrf token 值的 cookie 名称
  • xsrfHeaderName —— 带有 xsrf token 值 http head 名称
  • onUploadProgress —— 允许在上传过程中的做一些操作
  • onDownloadProgress —— 允许在下载过程中的做一些操作
  • maxContentLength —— 定义了接收到的response响应数据的最大长度。
  • validateStatus —— validateStatus定义了根据HTTP响应状态码决定是否接收或拒绝获取到的promise。如果 validateStatus 返回 true (或设置为 null 或 undefined ),promise将被接收;否则,promise将被拒绝。
    maxRedirects —— maxRedirects定义了在node.js中redirect的最大值,如果设置为0,则没有redirect。
  • httpAgent —— 定义在使用http请求时的代理
  • httpsAgent —— 定义在使用https请求时的代理
  • proxy —— proxy定义代理服务器的主机名和端口,auth
  • cancelToken —— cancelToken定义一个 cancel token 用于取消请求

我们发现有一个headers参数,那么对上面的代码修改:


  
  1. var vm = this
  2. this.$http.post(
  3. vm.testUrl,
  4. {"name":"痞子达"},
  5. {headers:{'Content-Type':'application/x-www-form-urlencoded'}})
  6. .then((response)=>{
  7. alert(response.data.msg);
  8. })

加入{headers:{'Content-Type':'application/x-www-form-urlencoded'}}
但这个时候还是没能够正确弹框,因为我们传过去的是key字符串,并且vlue是没有值的。

Paste_Image.png

后端打印出来是这样的:


  
  1. array(1) { ["{"name":"痞子达"}"]=> string(0) "" }

这必须获取不到啊,那我们尝试将其转换为query参数。
引入Qs,这个库是axios里面包含的,不需要再下载了。


  
  1. import Qs from 'qs'
  2. var vm = this
  3. var data = Qs.stringify({"name":"痞子达"});
  4. this.$http.post(vm.testUrl,data, {headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then((response)=>{
  5. alert(response.data.msg);
  6. })

再看:

Paste_Image.png

控制台看看那form-data:

Paste_Image.png

这才是我们熟悉的样子。

但是我们不能每次请求都写一遍config,太麻烦了。
在入口文件main.js修改:


  
  1. #创建一个axios实例
  2. var axios_instance = axios.create({
  3. #config里面有这个transformRquest,这个选项会在发送参数前进行处理。
  4. #这时候我们通过Qs.stringify转换为表单查询参数
  5. transformRequest: [function (data) {
  6. data = Qs.stringify(data);
  7. return data;
  8. }],
  9. #设置Content-Type
  10. headers:{'Content-Type':'application/x-www-form-urlencoded'}
  11. })
  12. Vue.use(VueAxios, axios_instance)

ok,以后发起http请求,如下即可:


  
  1. var vm = this
  2. this.$http.post(vm.url,data).then((response)=>{
  3. alert(response.data.msg);
  4. })

其他的用法和配置大家可以深入研究。

为什么放弃vue-resource,可以看这里:
https://github.com/vuefe/vuefe.github.io/issues/186

				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>

转自https://blog.csdn.net/nihaoqiulinhe/article/details/79084755

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值