Trust
Trust
  • 发布:2016-07-19 20:30
  • 更新:2016-07-19 20:30
  • 阅读:7459

【文档】解决 MUI v3.2.0 headers 为 {'Content-Type': 'application/json'} 发起 POST 请求异常的问题

分类:MUI

Mui v3.2.0中ajax设置headers为{'Content-Type': 'application/json'}发起post请求,后端接收不到数据的解决方案(php为例)

问题场景

php部分

<?php  
    $name = $_POST['name'];  
    $password = $_POST['password'];  
    var_dump($name);  
    var_dump($password);  
?>  

mui.ajax()部分

mui.ajax({  
    url: 'http://192.168.12.74:80/test01.php',  
    type: 'post',  
        headers:{'Content-Type': 'application/json'},  
    data: {  
        name: 'dcloud',  
        password: '123456'  
    },  
    success: function(data) {  
        console.log(data);  
    },  
    error: function(xhr, type, errorThrown) {  
        console.log(type);  
    }  
});  

控制台信息

Notice: Undefined index: name in test01.php on line 2
Notice: Undefined index: password in test01.php on line 3
我们按照通常的post方法去读取数据,发现并没有name和password这两个参数。

问题分析

可以参看下这篇文章《四种常见的 POST 提交数据方式》
当application/json这个Content-Type作为响应头时,我们需要手动处理一下:
从php://input 里获得原始输入流,再json_decode成对象。

方案一

php部分

<?php  
if ($_SERVER["CONTENT_TYPE"] == "application/json") {  
    $input = file_get_contents('php://input');  
    var_dump($input);  
    $object = json_decode($input);  
    $name = $object->name;  
    var_dump($name);  
}  
?>  

控制台信息一

'name=dcloud&password=123456' test01.php on line 4
null test01.php on line 7
此时,$input并不是一串json字符串,所以我们用json_decode去转换依旧是失败的,并不能拿到我们想要的数据。

mui.ajax()部分

mui.ajax()默认会对data里面的数据进行序列化,最终导致php接受到的是序列化以后的字符串。我们需要禁用对data的序列化(processData:false),并把参数对象序列化成json字符串(JSON.stringify())传给data。

mui.ajax({  
    url: 'http://192.168.12.74:80/test01.php',  
    type: 'post',  
    headers: {  
        'Content-Type': 'application/json'  
    },  
    processData: false,  
    data: JSON.stringify({  
        name: 'dcloud',  
        password: '123456'  
    }),  
    success: function(data) {  
        console.log(data);  
    },  
    error: function(xhr, type, errorThrown) {  
        console.log(type);  
    }  
});  

控制台信息二

'dcloud' test01.php on line 7
name参数的值被正确解析,问题解决。

方案二

只需修改php部分即可,方案一中我们在未设置processData属性为false时,获取的是一串序列化后的字符串'name=dcloud&password=123456'。我们对字符串进行截取,同样可以解析出我们想要的参数数据。

php部分

<?php  
    if($_SERVER["CONTENT_TYPE"]=="application/json"){  
        $input = file_get_contents('php://input');  
        $arr = explode("&", $input);  
    $narr = explode("=", $arr[0]);  
    $parr = explode("=", $arr[1]);  
    $name = $narr[1];  
    $password = $parr[1];  
        var_dump($name);  
        var_dump($password);  
    }  
?>  

mui.ajax()部分:

mui.ajax({  
    url: 'http://192.168.12.74:80/test02.php',  
    type: 'post',  
    headers: {  
        'Content-Type': 'application/json'  
    },  
    data: {  
        name: 'dcloud',  
        password: '123456'  
    },  
    success: function(data) {  
        console.log(data);  
    },  
    error: function(xhr, type, errorThrown) {  
        console.log(type);  
    }  
});  

控制台信息

'dcloud' test02.php on line 9
'123456' test02.php on line 10
通过对字符串的截取分组,最终取得我们想要的参数数据,但是此方法的缺点在于参数的顺序不明或数量太多会非常繁琐。

后续解决

Mui v3.3.0,将对此情况进行更加精确的处理,3.2.0版本遇到此问题可按照上面的方式进行处理数据。

3 关注 分享
whucj88@163.com skysowe houheaven

要回复文章请先登录注册

houheaven

houheaven

这个方式确实能够解决问题,但是无法使用 $_POST[] 方式来获取请求的数据,这个方案能够解决这个问题:https://ask.dcloud.net.cn/article/12967
2017-12-13 20:25
1119365045@qq.com

1119365045@qq.com

现在按照这个方法弄还是不行啊
怎么回事啊
2017-08-14 12:18
admin@zhangp.cn

admin@zhangp.cn

回复 m15940551159@163.com:
file_get_contents("php://input")
2017-07-04 17:37
1231312312312

1231312312312

回复 skysowe:
我的参数名是 bean.patient.name 这类的,后台是jsp的怎么都接收不到参数
2017-05-31 15:31
skysowe

skysowe

回复 skysowe:
mui 3.6版好像已经解决了这个问题了,用第一种方案的话

data: {
name : input_name,
password : input_pwd
},

//mui已经改进,下面的方法跟上面的结果一样
data: JSON.stringify({
name: input_name,
password: input_pwd
}),
2017-03-12 14:17
skysowe

skysowe

刚好碰到mui中ajax发送数据的例子,楼主的文章帮了大忙了
2017-03-12 13:49
m15940551159@163.com

m15940551159@163.com

求问 如果php页面是laravel框架里的控制器 PHP输入流应该怎么写
2017-02-09 11:21
reallow

reallow

很好,使用常规POST方法后台无法获取数据,使用作者方法后用mui.ajax和plus.net.XMLHttpRequest都可以正常使用了。
2016-11-08 11:12
whucj88@163.com

whucj88@163.com

学习了
2016-11-07 19:01