资讯专栏INFORMATION COLUMN

解决PHP获取不了 React Native Fecth参数的问题

edagarli / 2005人阅读

摘要:使用进行网络请求推荐的形式进行数据处理。这个时候自己去搜索了下,提出了两种解决方案构建表单数据参考这里但是这个在自己的机器上并不生效。服务端解决方案获取里面的内容,在中可以这样写这个时候就可以打印出数据了。

React Native 使用 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为空数组。这个时候自己去搜索了下,提出了两种解决方案:

构建表单数据
function toQueryString(obj) {
    return obj ? Object.keys(obj).sort().map(function (key) {
        var val = obj[key];
        if (Array.isArray(val)) {
            return val.sort().map(function (val2) {
                return encodeURIComponent(key) + "=" + encodeURIComponent(val2);
            }).join("&");
        }

        return encodeURIComponent(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的支持。这个时候要做兼容我们的方案大致如下:

我们在fetch参数中设置了 header 设置 app 字段,加入app名称:ios-appname-1.8;

我们在服务端设置了一个钩子:在每次请求之前进行数据处理:

// 获取 app 进行数据集中处理
        if(!function_exists("apache_request_headers") ){
            $appName = $_SERVER["app"];
        }else{
            $appName =  apache_request_headers()["app"];
        }
        
        // 对 RN fetch 参数解码
        if($appName == "your settings") {
            $json = file_get_contents("php://input");
            $_POST = json_decode($json, TRUE );
        }

这样服务端就无需做大的改动了。

对 Fetch的简单封装

由于我们的前端之前用 jquery较多,我们做了一个简单的fetch封装:

var App = {

    config: {

        api: "your host",
        // app 版本号
        version: 1.1,

        debug: 1,
    },

    serialize : function (obj) {
        var str = [];
        for (var p in obj)
            if (obj.hasOwnProperty(p)) {
                str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
            }
        return str.join("&");
    },

    // build random number
    random: function() {
        return ((new Date()).getTime() + Math.floor(Math.random() * 9999));
    },



    // core ajax handler
    send(url,options) {
        var isLogin = this.isLogin();
        var self = this;


        var defaultOptions = {
            method: "GET",
            error: function() {
                options.success({"errcode":501,"errstr":"系统繁忙,请稍候尝试"});
            },
            headers:{
                "Authorization": "your token",
                "Accept": "application/json",
                "Content-Type": "application/json",
                "App": "your app name"
            },
            data:{
                // prevent ajax cache if not set
                "_regq" : self.random()
            },
            dataType:"json",
            success: function(result) {}
        };

        var options = Object.assign({},defaultOptions,options);
        var httpMethod = options["method"].toLocaleUpperCase();
        var full_url = "";
        if(httpMethod === "GET") {
            full_url = this.config.api +  url + "?" + this.serialize(options.data);
        }else{
            // handle some to "POST"
            full_url = this.config.api +  url;
        }

        if(this.config.debug) {
            console.log("HTTP has finished %c" + httpMethod +  ":  %chttp://" + full_url,"color:red;","color:blue;");
        }
        options.url = full_url;


        var cb = options.success;

        // build body data
        if(options["method"] != "GET") {
            options.body = JSON.stringify(options.data);
        }

        // todo support for https
        return fetch("http://" + options.url,options)
               .then((response) =>  response.json())
               .then((res) => {
                    self.config.debug && console.log(res);
                    if(res.errcode == 101) {
                        return self.doLogin();
                    }

                    if(res.errcode != 0) {

                        self.handeErrcode(res);
                    }
                    return cb(res,res.errcode==0);
                })
                .catch((error) => {
                  console.warn(error);
                });
    },


    handeErrcode: function(result) {
        //
        if(result.errcode == 123){


            return false;
        }

        console.log(result);
        return this.sendMessage(result.errstr);
    },


    // 提示类

    sendMessage: function(msg,title) {
        if(!msg) {
            return false;
        }
        var title = title || "提示";

        AlertIOS.alert(title,msg);
    }

};

module.exports = App;

这样开发者可以这样使用:

App.send(url,{
    success: function(res,isSuccess) {
    }
})

更多内容详见: https://github.com/JackPu/react-native-core-lib

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79020.html

相关文章

  • 解决PHP获取不了 React Native Fecth参数问题

    摘要:使用进行网络请求推荐的形式进行数据处理。这个时候自己去搜索了下,提出了两种解决方案构建表单数据参考这里但是这个在自己的机器上并不生效。服务端解决方案获取里面的内容,在中可以这样写这个时候就可以打印出数据了。 React Native 使用 fetch 进行网络请求,推荐Promise的形式进行数据处理。官方的 Demo 如下: fetch(https://mywebsite.com/e...

    付伦 评论0 收藏0
  • 一篇文章让你学会如何选择 JS HTTP 请求库

    摘要:本文将带你了解不同请求的原理,以及如何为项目选择合适的请求库。小程序年微信小程序上线,随后各大平台都推出自己的小程序。下面为目前较火的请求库。支持微信小程序和浏览器是一个基于的请求库,可以用在微信小程序和浏览器中,对上述平台都做了兼容。 以前前端提到网络请求通常是指浏览器,但现在随着 Node.js、小程序的出现,网络请求不再局限于浏览器。本文将带你了解不同请求的原理,以及如何为项目选...

    Render 评论0 收藏0
  • 2018 PHP面试真题(包括详细解析)

    摘要:以下题目和解析分别来源于我的新书程序员面试笔试宝典程序员面试笔试真题解析。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。真题获得实例化对象所属类名字的函数是。 以下题目和解析分别来源于我的新书《PHP程序员面试笔试宝典》、《PHP程序员面试笔试真题解析》。 1、PHP常考基础 1、PHP与ASP、JSP有什么区别?ASP全名Active Server Page...

    pubdreamcc 评论0 收藏0
  • 论一个前端工程师如何快速学习,成长。准备自己35岁 【-原创精读】

    showImg(https://segmentfault.com/img/bVbw3tK?w=1240&h=827); 前端工程师这个岗位,真的是反人性的 我们来思考一个问题: 一个6年左右经验的前端工程师: 前面两年在用jQuery 期间一直在用React-native(一步一步踩坑过来的那种) 最近两年还在写微信小程序 下面一个2年经验的前端工程师: 并不会跨平台技术,他的两年工作都是Reac...

    RdouTyping 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<