【问题标题】:ReactJS Fetch drop-in replacement for this AJAX boilerplateReactJS Fetch 替代这个 AJAX 样板
【发布时间】:2019-02-07 19:51:30
【问题描述】:

背景:

以下AJAX 代码成功运行 (ReactJS + JQuery frontend, PHP backend)。

    const data = {request_type:"load_data", start:1, end:50};

    $.ajax({
        type: "POST",
        url: "http://localhost/site/server.php",
        data: data,
        dataType: "json", 
        success: (JSobject) => {
            this.setState({arr: JSobject.arr});
        }
    });

在 Chrome 开发工具中,server.php 的标头显示为“Form Data”,如下所示:

在 PHP 服务器后端,有这行代码:

    $request_type = $_POST["request_type"];

为了学习如何进行 Fetch(到目前为止,我一直避免使用它,主要是因为我的 AJAX 样板运行良好),我一直在尝试构建上述代码的替代品.

我试过了:

    const data = {request_type:"load_data", start:1, end:50};

    fetch("http://localhost/site/server.php", {
        method: "POST",
        body: data
    })
        .then((JSobject) => {
            this.setState({arr: JSobject.arr});
        });

但我得到这个 PHP 错误:

注意:未定义索引:.....server.php 中的 request_type

在 Chrome 开发工具中server.php 的标题显示如下:


所以,我尝试将数据更改为 JSON.stringify(data),如下所示:

    const data = {request_type:"load_data", start:1, end:50};

    fetch("http://localhost/site/server.php", {
        method: "POST",
        body: JSON.stringify(data)
    })
        .then((JSobject) => {
            this.setState({arr: JSobject.arr});
        });

但我仍然得到完全相同的 PHP 错误:

注意:未定义索引:.....server.php 中的 request_type

在 Chrome 开发工具中server.php 的标题显示如下:


出于普遍的挫败感(尽管这毫无意义,因为我仍在使用 JQuery),我想我会使用 JQuery 的$.param(),这肯定会奏效。

所以我尝试了这个:

    const data = $.param({request_type:"load_data", start:1, end:50});

    fetch("http://localhost/site/server.php", {
        method: "POST",
        body: data
    })
        .then((JSobject) => {
            this.setState({arr: JSobject.arr});
        });

仍然遇到同样的 PHP 错误

注意:未定义索引:.....server.php 中的 request_type

在 Chrome 开发工具中server.php 的标题显示如下:


我的问题:如何修改上面的 Fetch 代码,使其成为顶部 AJAX 代码的直接替代品。

我意识到使用水平线对某些人来说可能很麻烦。您可以允许自己相信它确实可以帮助我们很多普通人关注问题中发生的事情。

【问题讨论】:

    标签: ajax reactjs post http-post fetch-api


    【解决方案1】:

    为将来可能遇到此问题的其他人回答我自己的问题(也供我自己参考)。通过this linkthis link 找出答案。以下代码有效:

    fetch("http://localhost/site/server.php", {
        method: "POST",
        body: JSON.stringify(data)
    }).then(response => {
          return response.json();
       }).then((JSobject) => {
           this.setState({arr: JSobject.arr});
          });
    

    我不得不更改服务器上的一些 PHP 代码。最初的“看门人”代码是:

    $_POST = array_map("trim", $_POST);
    
    $request_type = $_POST["request_type"];
    

    这必须被注释掉:

    $_POST = array_map("trim", $_POST);   //this had to be commented out
    

    而这必须被添加:

    $content = trim(file_get_contents("php://input"));
    $_POST = json_decode($content, true);
    

    在 Chrome 开发工具中,server.php 的标头显示为“Request Payload”:


    我还看到了一些添加“headers”键的建议,如下所示:

    fetch("http://localhost/site/server.php", {
        method: "POST",
        headers: {"Content-Type": "application/x-www-form-urlencoded",},
        body: JSON.stringify(data)
    }).then(response => {
          return response.json();
       }).then((JSobject) => {
           this.setState({arr: JSobject.arr});
          });
    

    这也有效,但在 Chrome 开发工具中server.php 的标题显示为“Form Data”:


    另一种方法是将对象(要发送)包装在 JQuery 的 $.param() 中(我对此很感兴趣,因为我经常在客户端使用 $.param() 将键值附加到 form.serialize()在发送到服务器上的 PHP 之前)

    const data = $.param({request_type:"load_data", start:1, end:50});
    
    fetch("http://localhost/site/server.php", {
    method: "POST",
    headers: {"Content-Type": "application/x-www-form-urlencoded",},
    body: data
    }).then(response => {
       return response.json();
         }).then((JSobject) => {
          this.setState({arr: JSobject.arr});
           });
    

    这样做的好处是不需要对服务器端的代码进行任何更改。

    在 Chrome 开发工具中,server.php 的标头显示为“Form Data”:


    不使用 JQuery:

    Re: 前一种方法(使用$.param()),可以完全不使用JQuery,但是需要一些函数来链接javascript对象的键值对,同时将特殊字符正确编码为x- www-form-urlencoded(this link 解释了如何做到这一点)。

    例如,而不是这个:

    const data = $.param({request_type:"load_data", start:1, end:50});
    
    ...
    body: data
    

    一个人会这样做:

    const data = {request_type:"load_data", start:1, end:50};
    
    ...
    
    ...
    body: "request_type=load_data&start=1&end=50"
    

    【讨论】:

      猜你喜欢
      • 2019-06-03
      • 2017-11-15
      • 2011-11-03
      • 2020-02-29
      • 2019-12-22
      • 1970-01-01
      • 1970-01-01
      • 2019-08-18
      • 2023-01-11
      相关资源
      最近更新 更多