PHP获取不了React Native Fecth参数的解决办法
话不多说,我们直接来看示例
ReactNative使用fetch进行网络请求,推荐Promise的形式进行数据处理。
官方的Demo如下:
fetch('https://mywebsite.com/endpoint/',{
method:'POST',
headers:{
'Accept':'application/json',
'Content-Type':'application/json',
},
body:JSON.stringify({
username:'yourValue',
pass:'yourOtherValue',
})
}).then((response)=>response.json())
.then((res)=>{
console.log(res);
})
.catch((error)=>{
console.warn(error);
});
但是实际在进行开发的时候,却发现了php打印出$_POST为空数组。
这个时候自己去搜索了下,提出了两种解决方案:
一、构建表单数据
functiontoQueryString(obj){
returnobj?Object.keys(obj).sort().map(function(key){
varval=obj[key];
if(Array.isArray(val)){
returnval.sort().map(function(val2){
returnencodeURIComponent(key)+'='+encodeURIComponent(val2);
}).join('&');
}
returnencodeURIComponent(key)+'='+encodeURIComponent(val);
}).join('&'):'';
}
//fetch
body:toQueryString(obj)
但是这个在自己的机器上并不生效。
二、服务端解决方案
获取body里面的内容,在php中可以这样写:
$json=json_decode(file_get_contents('php://input'),true);
var_dump($json['username']);
这个时候就可以打印出数据了。然而,我们的问题是服务端的接口已经全部弄好了,而且不仅仅需要支持ios端,还需要web和Android的支持。这个时候要做兼容我们的方案大致如下:
1、我们在fetch参数中设置了header设置app字段,加入app名称:ios-appname-1.8;
2、我们在服务端设置了一个钩子:在每次请求之前进行数据处理:
//获取app进行数据集中处理
if(!function_exists('apache_request_headers')){
$appName=$_SERVER['app'];
}else{
$appName=apache_request_headers()['app'];
}
//对RNfetch参数解码
if($appName=='yoursettings'){
$json=file_get_contents('php://input');
$_POST=json_decode($json,TRUE);
}
这样服务端就无需做大的改动了。
对Fetch的简单封装
由于我们的前端之前用jquery较多,我们做了一个简单的fetch封装:
varApp={
config:{
api:'yourhost',
//app版本号
version:1.1,
debug:1,
},
serialize:function(obj){
varstr=[];
for(varpinobj)
if(obj.hasOwnProperty(p)){
str.push(encodeURIComponent(p)+"="+encodeURIComponent(obj[p]));
}
returnstr.join("&");
},
//buildrandomnumber
random:function(){
return((newDate()).getTime()+Math.floor(Math.random()*9999));
},
//coreajaxhandler
send(url,options){
varisLogin=this.isLogin();
varself=this;
vardefaultOptions={
method:'GET',
error:function(){
options.success({'errcode':501,'errstr':'系统繁忙,请稍候尝试'});
},
headers:{
'Authorization':'yourtoken',
'Accept':'application/json',
'Content-Type':'application/json',
'App':'yourappname'
},
data:{
//preventajaxcacheifnotset
'_regq':self.random()
},
dataType:'json',
success:function(result){}
};
varoptions=Object.assign({},defaultOptions,options);
varhttpMethod=options['method'].toLocaleUpperCase();
varfull_url='';
if(httpMethod==='GET'){
full_url=this.config.api+url+'?'+this.serialize(options.data);
}else{
//handlesometo'POST'
full_url=this.config.api+url;
}
if(this.config.debug){
console.log('HTTPhasfinished%c'+httpMethod+':%chttp://'+full_url,'color:red;','color:blue;');
}
options.url=full_url;
varcb=options.success;
//buildbodydata
if(options['method']!='GET'){
options.body=JSON.stringify(options.data);
}
//todosupportforhttps
returnfetch('http://'+options.url,options)
.then((response)=>response.json())
.then((res)=>{
self.config.debug&&console.log(res);
if(res.errcode==101){
returnself.doLogin();
}
if(res.errcode!=0){
self.handeErrcode(res);
}
returncb(res,res.errcode==0);
})
.catch((error)=>{
console.warn(error);
});
},
handeErrcode:function(result){
//
if(result.errcode==123){
returnfalse;
}
console.log(result);
returnthis.sendMessage(result.errstr);
},
//提示类
sendMessage:function(msg,title){
if(!msg){
returnfalse;
}
vartitle=title||'提示';
AlertIOS.alert(title,msg);
}
};
module.exports=App;
这样开发者可以这样使用:
App.send(url,{
success:function(res,isSuccess){
}
})
总结
好了,到这里PHP获取不了ReactNativeFecth参数的问题就基本解决结束了,希望本文对大家的学习与工作能有所帮助,如果有疑问或者问题可以留言进行交流。