背景:
以下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(数据),如下所示:
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
代码的替代品。
我意识到使用水平线对某些人来说可能很麻烦。您可以允许自己相信它确实有助于我们很多常规人员跟踪问题中发生的事情。
回答我自己的问题,为将来可能会遇到这个问题的人(以及我自己的参考)。通过this link和this 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"