Home > Blockchain >  PHP $_GET and $_POST issue when combined with the JavaScript fetch() API
PHP $_GET and $_POST issue when combined with the JavaScript fetch() API

Time:09-23

The Issue

I have a problem where I have seen similar questions in an albeit different context regards to $_POST and $_GET requests with PHP. A typical example being PHP mixing POST and GET Requests to one page

In my instance the GET is being taken from query string in a URL, and out of the box the functionality all works as expected when deleting an image component (a container that holds an image) from a page.

The problem I have is I am using using the JavaScript fetch() API for this deletion so that the page doesn't do a hard refresh. When this process happens with JavaScript fetch() the image component is removed from the page but when you refresh the page the image component reappears.

I am using almost identical code on a different page, and when this problem occurred, moving the GET request below the POST request solved the problem. Alas, this isn't happening this time (and on that other page there is only one potential POST request form).

All of the forms that use $_POST are processed on the same page that the forms themselves appear on (i.e. no action attribute is used). Only one POST request happens at any one time.

Question

My question is thus, how do I approach / solve this without using the dreaded $_REQUEST. I noticed one of the answers to the general problem of GET and POST suggested using if($_SERVER['REQUEST_METHOD'] == 'POST') { ... } but this isn't an option (I don't think) because there are three potential $_POST forms on the page that all have different functionality and name attributes.

Below are the GET and POST code blocks in the order in which they appear.

Note: I only included the PHP PDO for the 'remove image from board' code block because this is the only aspect with JavaScript fetch() and I know this works OK with no JavaScript. There is also potentially a lot of code I could share which I'm happy to do, but thought I'd post a slimmed down version of the code first in case there is an obvious answer that I'm completely missing. There is only one $_POST request executed at any one time.

There are header() functions in each POST block, although I don't see that being the source of the problem?

Also, this is all quite new to me.

JavaScript

// the form iteself
const fetchForms = document.querySelectorAll('.js-fetch-form'),

// <figure> element that is deleted
removeableImageComponent = document.querySelectorAll('.removeable-image-component');

// URL details
let myURL = new URL(window.location.href),
pagePath = myURL.pathname

fetchForms.forEach((item) => {
    item.addEventListener('submit', function (e) {
        if (e.submitter && e.submitter.classList.contains('js-delete-button')) {
            e.preventDefault();

            var formData = new FormData(this);

            formData.set(e.submitter.name, e.submitter.value);

            fetch(
                pagePath, {
                method: 'post',
                body: formData
            })
            .then(function(response) {

                if (response.status === 200) {
                    if (e.submitter && e.submitter.classList.contains('js-delete-button')) {
                        e.submitter.closest('.removeable-image-component').remove();
                    }
                }

                return response.text();

            }).catch(function(error) {
                console.error(error);
            })

        }
    })
})

HTML

<figure >
    <form  method="post">
        <input type="hidden" name="user-id" value="03">
        <img src="path/to/image.jpg">
        <button  name="image-delete" value="52">Remove from board</button>
    </form>
</figure>

PHP

// value from URL
if (isset($_GET['board-id']) ) {
    $boardId = $_GET['board-id'];
} else {
    header("Location: login.php");
    exit;
}

// UPDATE BOARD NAME
if(isset($_POST['submit-new-board-name'])) {

    // PDO updates to database

    header("Location: {$wwwRoot}/board.php?board-id={$boardId}"); exit;
    
    }
}

// ================
// DELETE THE BOARD
// ================

if (isset($_POST['delete-board'])) {

    // PDO updates to database

    header("Location: {$wwwRoot}/boards?id={$sessionId}"); exit;
}

// =======================
// REMOVE IMAGE FROM BOARD
// =======================

if(isset($_POST['image-delete'])) {

    $imageId = $_POST['image-id'];

    $stmt = $connection->prepare("DELETE FROM boards_images WHERE board_id = :board_id AND image_id = :image_id");
    $stmt->execute([
    ':board_id'=>$dbBoardId,
    ':image_id'=>$imageId
    ]);

    header("Location: {$wwwRoot}/board?board-id={$dbBoardId}"); exit;
}

CodePudding user response:

Change

            fetch(
                pagePath, {
                method: 'post',
                body: formData
            })

to

            fetch(
                myURL, {
                method: 'post',
                body: formData
            })

pagePath is the URL without the scheme or query parameters, so ?board-id=### is missing. To emulate how the normal form submission works when you leave out the action URL, you should submit to the entire URL.

  • Related