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参数的问题就基本解决结束了,希望本文对大家的学习与工作能有所帮助,如果有疑问或者问题可以留言进行交流。