Asynchroniczny request do backendu

0

Dzień dobry,
próbuje zapisać dane do bazy danych MySQL, ale niestety program tego nie robi. Serwer PHP i MYSQL działa lokalnie na XAMPie. Pobieranie danych z bazy działa bez problemu, tylko problem jest z zapisem. Na potrzeby testu została ustawiona sztywnie kwota w postaci 2000.

Swal.fire({
    title: 'Czy na pewno dodać rachunek?',
    showDenyButton: false,
    showCancelButton: true,
    confirmButtonText: 'TAK',
    confirmButtonColor: "green",
    cancelButtonColor: "red",
    cancelButtonText: `NIE`,
    progressStepsDistance: 10
  }).then((result) => {
    /* Read more about isConfirmed, isDenied below */
    if (result.isConfirmed) {
      Zapisz_Dane_Do_Bazy();
      Swal.fire('Rachunek dodany!', '', 'success');

    } else if (result.isDenied) {
      Swal.fire('Rachunek nie został zapisany', '', 'info')
    }
  })
const Zapisz_Dane_Do_Bazy = () => {
    fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
    method: 'post',
  headers: {'Content-Type':'application/json'},
    body: {
     "kwota": 2000
    }
   });
  }

Zawartość pliku: rachunek_dodaj.php

<?php
include "polaczeniebazy.php";
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With");
header("Content-Type: application/json; charset=UTF-8");
if ($_POST['kwota']) {
     $wykonaj_sql = mysqli_query($polaczenie_mysql,"INSERT INTO rachunki (kwota) VALUES (".$_POST['kwota'].")");
}
?>

Uprawnienia użytkownika w panelu phpmyadmin:

screenshot-20221129220154.png
Gdy wykonam polecenie INSERT INTO rachunki (kwota) VALUES (2000) bezpośrednio z poziomu PhpMyAdmin wówczas wszystko działa.
W konsoli w przeglądarce jak i terminalu w Visual Code nie ma żadnego błędu związanego z problemem podczas zapisu danych do bazy.

Pozdrawiam,
Łukasz

Aktualizacja
Teraz zmodyfikowałem mój kod do takiej postaci:

fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
   method: 'post',
   headers: {'Content-Type':'application/json'},
   body: {
    kwota: '2000'
   }
  })
  .then((response) => response.json())
  .then((result) => {
    console.log('Success:', result);
  })
  .catch((error) => {
    console.error('Error:', error);
  });

i wypluło mi w konsoli takie błędy:

Error: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data react_devtools_backend.js:4026:25
    overrideMethod react_devtools_backend.js:4026
    Zapisz_Dane_Do_Bazy rachunek_dodaj.js:51
    (asynchroniczny: promise callback)
    Zapisz_Dane_Do_Bazy rachunek_dodaj.js:49
    Zapisz_Dane rachunek_dodaj.js:136
    (asynchroniczny: promise callback)
    then sweetalert2.all.js:3731
    Zapisz_Dane rachunek_dodaj.js:133
    React 23
    js index.js:9
    factory react refresh:6
    Webpack 3

Aktualizacja 2

  fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
    method: 'POST',
  headers: {'Content-Type':'application/json'},
  body: JSON.stringify({
    kwota: '2000'
    })
   })
   .then((response) => response.json())
   .then((result) => {
     console.log('Success:', result);
   })
   .catch((error) => {
     console.error('Error:', error);
   });

w konsoli w Chrome dostałem info że problem występuje w wierszu 45:

screenshot-20221129230037.png

teraz doinstalowałem wtyczkę React Developer Tools dla Chrome i mam pełniejszy komunikat:

screenshot-20221129230523.png

Powyższy problem z CORS zniknął po modyfikacji kodu:

let headers = new Headers();
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');

fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
  method: 'POST',
  headers: {'Content-Type':'application/json'},
  body: JSON.stringify({
    kwota: '2000'
    })
 })
 .then((response) => response.json())
 .then((result) => {
   console.log('Success:', result);
 })
 .catch((error) => {
   console.error('Error:', error);
 });

ale teraz mam błąd:

screenshot-20221129231817.png

1
body: JSON.stringify({
kwota: '2000'
})
0

A naprawienie tego pierwszego bledu z "unikalną wartością propsa key w Reactcie" nie rozwiązuje przy okazji drugiego problemu?

0
virusek391 napisał(a):
<?php
include "polaczeniebazy.php";
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With");
header("Content-Type: application/json; charset=UTF-8");
if ($_POST['kwota']) {
     $wykonaj_sql = mysqli_query($polaczenie_mysql,"INSERT INTO rachunki (kwota) VALUES (".$_POST['kwota'].")");
}
?>

[...]

fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
   method: 'post',
   headers: {'Content-Type':'application/json'},
   body: {
    kwota: '2000'
   }
  })
  .then((response) => response.json())
  .then((result) => {
    console.log('Success:', result);
  })
  .catch((error) => {
    console.error('Error:', error);
  });

i wypluło mi w konsoli takie błędy:

Error: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data react_devtools_backend.js:4026:25
    overrideMethod react_devtools_backend.js:4026
    Zapisz_Dane_Do_Bazy rachunek_dodaj.js:51
    (asynchroniczny: promise callback)
    Zapisz_Dane_Do_Bazy rachunek_dodaj.js:49
    Zapisz_Dane rachunek_dodaj.js:136
    (asynchroniczny: promise callback)
    then sweetalert2.all.js:3731
    Zapisz_Dane rachunek_dodaj.js:133
    React 23
    js index.js:9
    factory react refresh:6
    Webpack 3

To wygląda, jakby JS nie umiał rozparsować odpowiedzi Twojego backendu.

Zmień kod w PHP na taki:

  1. if ($_POST['kwota']) {
       $wykonaj_sql = mysqli_query($polaczenie_mysql,"INSERT INTO rachunki (kwota) VALUES (".$_POST['kwota'].")");
       echo json_encode(['success' => true]);
    } else {
       http_response_code(400);
       echo json_encode(['success' => false]);
    }
    
  2. Zabierz zamykający ?>, bo on Ci może wyrenderować znaki które mogą być uznane za niepoprawne. W PHP ?> to jest to samo co echo.
virusek391 napisał(a):

Aktualizacja 2

  fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
      method: 'POST',
      headers: {'Content-Type':'application/json'},
      body: JSON.stringify({kwota: '2000'})
    })
   .then((response) => response.json())
   .then((result) => {
     console.log('Success:', result);
   })
   .catch((error) => {
     console.error('Error:', error);
   });

teraz doinstalowałem wtyczkę React Developer Tools dla Chrome i mam pełniejszy komunikat:

screenshot-20221129230523.png

Powyższy problem z CORS zniknął po modyfikacji kodu:

No to tak, to wygląda jak CORS. Dobrze zrobiłeś.

virusek391 napisał(a):

ale teraz mam błąd:
screenshot-20221129231817.png

No jak już mówili przedmówcy, to jest typowo Reactowy błąd, to już Ci zostało wyjaśnione.

0
Riddle napisał(a):
virusek391 napisał(a):
<?php
include "polaczeniebazy.php";
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With");
header("Content-Type: application/json; charset=UTF-8");
if ($_POST['kwota']) {
     $wykonaj_sql = mysqli_query($polaczenie_mysql,"INSERT INTO rachunki (kwota) VALUES (".$_POST['kwota'].")");
}
?>

[...]

fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
   method: 'post',
   headers: {'Content-Type':'application/json'},
   body: {
    kwota: '2000'
   }
  })
  .then((response) => response.json())
  .then((result) => {
    console.log('Success:', result);
  })
  .catch((error) => {
    console.error('Error:', error);
  });

i wypluło mi w konsoli takie błędy:

Error: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data react_devtools_backend.js:4026:25
    overrideMethod react_devtools_backend.js:4026
    Zapisz_Dane_Do_Bazy rachunek_dodaj.js:51
    (asynchroniczny: promise callback)
    Zapisz_Dane_Do_Bazy rachunek_dodaj.js:49
    Zapisz_Dane rachunek_dodaj.js:136
    (asynchroniczny: promise callback)
    then sweetalert2.all.js:3731
    Zapisz_Dane rachunek_dodaj.js:133
    React 23
    js index.js:9
    factory react refresh:6
    Webpack 3

To wygląda, jakby JS nie umiał rozparsować odpowiedzi Twojego backendu.

Zmień kod w PHP na taki:

  1. if ($_POST['kwota']) {
       $wykonaj_sql = mysqli_query($polaczenie_mysql,"INSERT INTO rachunki (kwota) VALUES (".$_POST['kwota'].")");
       echo json_encode(['success' => true]);
    } else {
       http_response_code(400);
       echo json_encode(['success' => false]);
    }
    
  2. Zabierz zamykający ?>, bo on Ci może wyrenderować znaki które mogą być uznane za niepoprawne. W PHP ?> to jest to samo co echo.
virusek391 napisał(a):

Aktualizacja 2

  fetch('http://localhost:8080/baza/rachunek_dodaj.php', {
      method: 'POST',
      headers: {'Content-Type':'application/json'},
      body: JSON.stringify({kwota: '2000'})
    })
   .then((response) => response.json())
   .then((result) => {
     console.log('Success:', result);
   })
   .catch((error) => {
     console.error('Error:', error);
   });

teraz doinstalowałem wtyczkę React Developer Tools dla Chrome i mam pełniejszy komunikat:

screenshot-20221129230523.png

Powyższy problem z CORS zniknął po modyfikacji kodu:

No to tak, to wygląda jak CORS. Dobrze zrobiłeś.

virusek391 napisał(a):

ale teraz mam błąd:
screenshot-20221129231817.png

No jak już mówili przedmówcy, to jest typowo Reactowy błąd, to już Ci zostało wyjaśnione.

Okazało się że plik rachunek_dodaj.php miał trochę nie właściwą strukturę, ponieważ otrzymywał dane w formacie JSON, a tak naprawdę nie potrafił je rozkodować.
Poniższy kod rozwiązał mój problem:

<?php
include "polaczeniebazy.php";
header("Content-Type: application/json; charset=UTF-8");

$dane_json = file_get_contents('php://input');
$_POST = json_decode($dane_json, true);

if ($_POST["kwota"]) {
    $wykonaj_sql = mysqli_query($polaczenie_mysql,"INSERT INTO rachunki (kwota) VALUES (".$_POST["kwota"].")");
    echo json_encode(['success' => true]);
 } else {
    http_response_code(400);
    echo json_encode(['success' => false]);
 }
 ?>
0

@virusek391: trochę dziwnie Ci to wyszło. Pobierasz dane z raw Input i przypisujesz do $_POST.
albo zrób to jakąś lokalną zmienną, albo sprawdź co jest w samym $_POST i z stamtąd pobieraj json`a do dekodowania. Tak narażasz się na błędy.
Dobrze by było żebyś też to jakoś walidował, sprawdzał czy dane to json, czy kwota to wartość numeryczna i czy nie ma tam SQL Injection.

1 użytkowników online, w tym zalogowanych: 0, gości: 1