无法使用 PHP 删除数据库条目,使用来自 REACT 的 DELETE 请求。

huangapple go评论55阅读模式
英文:

Can not delete database entry with PHP, with DELETE request sent from REACT

问题

function Delete() {
    const form = new FormData();
    for (var i = 0; i < selected.length; i++) {
        form.append(i, selected[i]);
    }
    console.log(form)
    axios.delete(url, form)
    navigate(`/`)
}
header('Access-Control-Allow-Origin: http://localhost:3000');
header("Access-Control-Allow-Methods: GET, POST, DELETE");
$servername = "localhost";
$username = "root";
$password = "";
$conn = new mysqli($servername, $username, $password, 'commerce');
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
    case "DELETE":
        parse_str(file_get_contents("php://input"), $_DELETE);
        for ($i = 0; $_DELETE; $i++) {
            $sku = $_DELETE[$i];
            $delete = $conn->prepare("DELETE FROM baseinfos WHERE sku='$sku'");
            $delete->execute();
        }
        break;
}

问题描述:在REACT中使用axios发送DELETE请求来尝试删除数据库条目。在代码中首先遍历名为"selected"的数组,并将其作为数字分配给表单的键。例如,表单中的第一个键是1,对应于"selected"的第一个值,以此类推。然后是PHP代码部分,该部分用于处理从前端发送的DELETE请求,删除对应数据库中的条目。然而,执行后什么都没有发生,甚至没有抛出错误。请问我应该怎么做?

英文:

I am trying to delete database entry with DELETE http request sent from axios in REACT.

    function Delete() {
        const form = new FormData();
        for (var i = 0; i &lt; selected.length; i++) {
            form.append(i, selected[i]);
          }
        console.log(form)
        axios.delete(url, form)
        navigate(`/`)
    }

As you can see here, I iterate over "selected" which is an array and assign keys in the form as numbers. For example first key in form is 1 with first "selected" value and so on. Then comes the PHP code.

header(&#39;Access-Control-Allow-Origin: http://localhost:3000&#39;);
header(&quot;Access-Control-Allow-Methods: GET, POST, DELETE&quot;);
$servername = &quot;localhost&quot;;
$username = &quot;root&quot;;
$password = &quot;&quot;;
$conn = new mysqli($servername, $username, $password, &#39;commerce&#39;);
$method = $_SERVER[&#39;REQUEST_METHOD&#39;];
switch ($method) {
  case &quot;DELETE&quot;:
    parse_str(file_get_contents(&quot;php://input&quot;), $_DELETE);
    for ($i = 0; $_DELETE; $i++) {
      $sku = $_DELETE[$i];
      $delete = $conn-&gt;prepare(&quot;DELETE FROM baseinfos WHERE sku=&#39;$sku&#39;&quot;);
      $delete-&gt;execute();
    }
    break;

Here I am supposed to get the values of DELETE form, iterate over key values (which are numbers and iteration should work) and delete the corresponding entries in the database. Nothing happens, not even an error is thrown. What should I do?

答案1

得分: 0

DELETE请求中的请求体通常不是一个好主意,通常应该避免使用。DELETE请求的目的是删除由URL标识的资源。

在您的情况下,看起来您想定义一个通用操作,用于删除多种不同的项目。对于这种情况,POST 更加合适。

服务器和客户端可能会忽略DELETE请求的请求体,因为DELETE请求的请求体没有预期的含义。

根据最新的HTTP规范:

虽然请求消息的构建与所使用的方法无关,但在DELETE请求中接收的内容没有通常定义的语义,不能改变请求的含义或目标,并且可能导致一些实现拒绝请求并关闭连接,因为它有潜在的请求劫持攻击的可能性(请参阅[HTTP/1.1]第11.2节)。除非直接向之前已在带内或带外指示此类请求具有目的并将得到充分支持的源服务器发送此类请求,否则客户端不应生成DELETE请求中的内容。源服务器不应依赖于私人协议来接收内容,因为HTTP通信的参与者通常不知道请求链上的中介。

https://www.rfc-editor.org/rfc/rfc9110.html#name-delete

英文:

Bodies on DELETE requests are not a good idea and generally should be avoided. The purpose of a DELETE request is to delete the resource identified by the URL you are using.

In your case, it looks like you want to define a generic operation that deletes a number of different items. POST is more appropriate for this.

Servers and clients may drop DELETE request bodies because DELETE request bodies are not intended to be meaningful.

From the latest HTTP specification:

>Although request message framing is independent of the method used, content received in a DELETE request has no generally defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]). A client SHOULD NOT generate content in a DELETE request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.

https://www.rfc-editor.org/rfc/rfc9110.html#name-delete

答案2

得分: -1

第一个问题是 axios.delete() 的签名为:

> axios.delete(url[, config])

如果你想发送请求体,请在配置对象的 data 属性中进行。

其次,在请求体中发送 FormData 会使用 content-type: multipart/form-data,而这不是 parse_str() 所支持的格式。

> 将字符串解析为通过 URL 传递的查询字符串

我强烈建议改用 JSON。直接发送 selected 数组即可:

axios.delete(url, { data: selected });

Axios 会将其编码为 JSON,并自动设置适当的 content-type: application/json 头。

要在 PHP 端读取这个,请使用以下方法:

$skusToDelete = json_decode(file_get_contents('php://input'));
$stmt = $conn->prepare('DELETE FROM baseinfos WHERE sku = ?');
$stmt->bind_param('s', $sku);
foreach ($skusToDelete as $sku) {
    $stmt->execute();
}

请注意,我使用了绑定的 SQL 查询参数,这是 更安全的做法。你只需要准备一次查询语句并绑定参数,然后可以在循环中执行它。

英文:

The first problem is that the signature for axios.delete() is

> axios.delete(url[, config])

If you want to send a request body, you need to do so in the config object's data property.

Secondly, sending FormData in the request body uses content-type: multipart/form-data which is not the format parse_str() works with.

> Parses string as if it were the query string passed via a URL

I would highly recommend using JSON for this instead. Simply send the selected array directly

axios.delete(url, { data: selected });

Axios will encode this as JSON and set the appropriate content-type: application/json header automatically.

To read this on the PHP side, use the following

$skusToDelete = json_decode(file_get_contents(&#39;php://input&#39;));
$stmt = $conn-&gt;prepare(&#39;DELETE FROM baseinfos WHERE sku = ?&#39;);
$stmt-&gt;bind_param(&#39;s&#39;, $sku);
foreach ($skusToDelete as $sku) {
    $stmt-&gt;execute();
}

Note that I've used bound SQL query parameters which are a lot safer. You also only need prepare a query statement and bind parameters once. It can then be executed in a loop.

huangapple
  • 本文由 发表于 2023年6月29日 14:19:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76578481.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定