使用Fetch API向PHP服务器发送数据(首选POST方法和JSON格式)。

5

这是我第一次尝试使用Fetch API,我在向PHP服务器发送POST数据的过程中遇到了问题。

我正在摆脱$.ajax,尝试使用纯JavaScript解决与不同服务器(有时是本地的,有时不是)通信的问题。现在我正在尝试理解Fetch API,即使它很简单和直观,但我遇到了一个奇怪且意外的问题:

  • 我无法向PHP服务器发送JSON post请求

  • 我可以将form-data post请求发送到本地PHP

  • 我无法将form-data post请求发送到Web URL PHP

我可以从上述所有内容(显然)检索数据,但奇怪的是什么都没有到达。$_SERVER['REQUEST_METHOD']通过我可以看到,当我使用本地路径时,我得到了我所要求的“POST”,但当我使用Web URL时,由于某种我不理解的原因,它会更改为GET

url="/";
url="www.something.com";
fetch(url, {
    method: 'POST',
    body: JSON.stringify({
        test: "toast",
    })
})
.then(function(response) {
    return response.text();
})
.then(function(data) {
    console.log(data);
});

我只想以一种稳定和清晰的方式发送和接收数据,不需要使用jquery、库等。我只想发送一个JSON {"test":"toast"}并在检查$_POST变量时在PHP文件中找到它。

更新

本地和Web URL的问题似乎在于这个差异: www.something.com/test => www.something.com/test/index.php。 没有index.php出现了某些原因后拒绝了POST数据(但仍然读取了echoed信息)。但关于JSON的问题仍然存在。

  • 我无法将JSON post发送到PHP

  • 我可以将表单数据post发送到PHP

更新

我发现$_POST和$_GET与Fetch API不兼容。您必须使用php://input来获取发送到服务器的所有数据。

不知道为什么。有更好的解决方案吗?为什么ajax和XMLHttpRequest没有这种问题?

注意: 如果您希望数据被识别为json,您必须通过头指定,即使以前从未请求过,那么现在为什么? Fetch API是否缺少某些内容?

header('Content-Type: application/json');

$test=json_decode(file_get_contents("php://input"));
//some code
echo json_encode($test);

我不确定。但是我尝试了你的代码,它对我非常有效。也许你可以重新检查一下你正在尝试发送数据的URL。 - verisimilitude
你试过用JSON了吗?我刚刚更新了。 - Andrea
2个回答

3

使用Fetch API有两种方式:

let response = await fetch(url,[Options]);

if (response.ok) { // if HTTP-status is 200-299
  // get the response body (the method explained below)
  let json = await response.json();
} else {
  alert("HTTP-Error: " + response.status);
}

第二种方法是使用纯Promise语法:
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
  .then(response => response.json())
  .then(commits => alert(commits[0].author.login));

现在让我们谈谈选项和数据: 您的数据必须是一个像这样的JavaScript对象:
      let data = {
        test: "toast",
      };

那么,您可以像这样配置您的头信息:
let headers: {
       "Content-Type": "application/json"
      }
  };

最终使用fetch的方式如下:

let response = await fetch(url, {
        method: "POST",
        headers:headers,
        body: JSON.stringify(data)
      });

我认为你的问题是使用了FormData而不是字符串化的JavaScript对象。

1
谢谢,解释得非常好!但不幸的是,它仍然存在我之前尝试时遇到的相同问题...我查阅了许多文章,但仍然无法找到为什么会出现这种问题 :(关于FormData和JSON,我发现在php中,使用Fetch API是唯一的方法。而且它有效!(就像你的例子一样)但只能在本地使用... - Andrea
更新:似乎与Web URL有关的问题在于这个差异:link => link。由于某种原因,没有index.php会拒绝POST数据(但仍然读取回显信息)。但JSON的问题仍然存在。 - Andrea
1
@Andrea,我在fetch设置中使用了formDatamode:'no-cors'找到了一个解决方案。请查看这个答案 - f.llanquipichun

1
希望有人能找到这个答案。我正在使用Codeigniter 3.1.11,得到了朋友的帮助后找到了答案。
控制器
class YourController extends CI_Controller
{
    public function yourMethod() {

        // THIS CODE IS A MUST!
        $input = json_decode(file_get_contents('php://input'), true);

        // You get the data you sent via FETCH
        var_dump($this->input->post('testdata'));
    }
}

获取 POST JavaScript

let postData = new FormData();
postData.append('testdata', 123);
                            
fetch('http://localhost/your-app-name/yourcontroller/yourMethod', {
    method: 'POST',
    mode: 'no-cors',
    headers: {
        "Content-Type": "application/json"
    },
    body: postData
}).then((res) => {
    console.log(res);
    }).catch(console.log);

要查看使用Fetch发送或获取的数据预览,您可以进行检查,在“网络”选项卡中,点击“名称”表格中的“yourMethod”,然后转到“预览”选项卡。在预览中,您可以看到123。


这个也在服务器上测试过了吗,还是只在本地测试的? - SpyderScript

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接