• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

NodeJS i MongoDB - obsługa usuwania elementu

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
310 wizyt
pytanie zadane 7 czerwca 2020 w JavaScript przez Allen Obywatel (1,010 p.)

Chcę usunąć element z mongodb. Pojawia się następujący błąd i nie mam pojęcia co może być nie tak:

router.delete('/library/:id', (req, res) => {
  console.log(req.params.id);
  Book.deleteOne({ _id: req.params.id }, (err) => {
    if(err) console.log(err);
  });
  res.redirect('library');
});
<form action="/library/<%= book._id %>" method="DELETE" class="delete-btn-form">
                <div class="delete-btn"></div>
</form>

Id jest poprawnie wyświetlane w konsoli w 2 inii.

komentarz 7 czerwca 2020 przez ScriptyChris Mędrzec (190,190 p.)
Wstaw proszę wyraźniejszy screen lub pokaż te błędy w formie tekstu.
komentarz 7 czerwca 2020 przez Allen Obywatel (1,010 p.)
GET http://localhost:5000/library/5ed9f56036f81d215c4ea5cd? 404 (Not Found).

Dwa poniższe błędy odnoszą się do innego zagadnienia (ładowania zdjęcia).
komentarz 7 czerwca 2020 przez ScriptyChris Mędrzec (190,190 p.)

Czy serwer na pewno nasłuchuje na porcie 5000 i jest uruchomiony? Jeśli korzystasz z expressa, to wydaje mi się, że metoda delete nasłuchuje na request właśnie DELETE, a nie GET.

1 odpowiedź

+1 głos
odpowiedź 7 czerwca 2020 przez Comandeer Guru (606,120 p.)

Jeśli router nasłuchuje na metodę DELETE, to nie obsłuży formularza wysłanego metodą GET (bo ta metoda jest używana, jeśli formularz ma atrybut [method] o nieznanej wartości). NIestety, z poziomu przeglądarki takie żądanie da się wysłać tylko Ajaksem, formularze nie mają takiej możliwości.

komentarz 7 czerwca 2020 przez ScriptyChris Mędrzec (190,190 p.)

Dopiero zauważyłem, że form nie obsługuje atrybutu method z wartością DELETE, a właściwie to z wartościami innymi niż GET, POST i DIALOG. Z czego wynika to ograniczenie?

1
komentarz 7 czerwca 2020 przez Comandeer Guru (606,120 p.)

Bo nigdy nie było woli ze strony przeglądarek, by wspierać inne metody. Był projekt rozszerzenia specyfikacji HTML5, ale nigdy nie został wdrożony.

Zresztą metody inne niż GET i POST są na tyle mało popularne, że decyzja ta ma dość praktyczne uzasadnienie. Zwłaszcza, że implementacja nowych metod skomplikowałaby model procesowania formularzy.

komentarz 8 czerwca 2020 przez Tomek Sochacki Ekspert (227,490 p.)

Zresztą metody inne niż GET i POST są na tyle mało popularne

czy ja wiem... w sporej części API różnych mikrousług do jakich strzelam czy to z frontu czy back-endowo usługa-usluga DELETE występuje całkiem często... tak samo jak PUT, to metody jak wszystkie inne :)

komentarz 8 czerwca 2020 przez ScriptyChris Mędrzec (190,190 p.)
Zastanawiam się, jak wysyłano formularze używające pozostałych (nieobsługiwanych) metod HTTP w czasach przed powstaniem (uformowaniem się) Ajaxa. Chyba, że wtedy wystarczało GET/POST. :)
komentarz 8 czerwca 2020 przez Allen Obywatel (1,010 p.)

@Comandeer, W takim razie powinienem zrezygnować z router.delete na rzecz router.post lub router.get? Przy metodzie post w tagu form i użyciu router.post wyświetla się komunikat "Strona localhost spowodowała zbyt wiele przekierowań". Próbowałem też skorzystać z method-override, ale pojawia się żaden błąd: GET http://localhost:5000/library/libraryPage.js net::ERR_ABORTED 404 (Not Found)

<form action="/library/<%= book._id %>?_method=DELETE" method="POST" class="delete-btn-form">
                <div class="delete-btn"></div>
</form>
 deleteBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      btn.submit();
    });
  });
router.delete('/library/:id', (req, res) => {
  console.log(req.params.id);
  Book.findOneAndDelete({ _id: req.params.id }, (err) => {
    if (err) console.log(err);
  });
    res.redirect('library');
});

 

1
komentarz 8 czerwca 2020 przez Comandeer Guru (606,120 p.)

To zależy. Jeśli chcesz móc dalej to robić zwykłym formularzem, to prawdopodobnie zamiana metody na POST będzie najprostszym wyjściem. Chyba że przesiądziesz się na Ajaksa. Z punktu widzenia API DELETE jest najsensowniejszym rozwiązaniem.

Zastanawiam się, jak wysyłano formularze używające pozostałych (nieobsługiwanych) metod HTTP w czasach przed powstaniem (uformowaniem się) Ajaxa. Chyba, że wtedy wystarczało GET/POST. :)

Wtedy najczęściej istniały monolitowe aplikacje, bez wyraźnego podziału na frontend i API na backendzie. Zaryzykowałbym stwierdzenie, że wówczas ten problem nie był taki istotny, bo i tak mieliśmy pełną kontrolę nad frontendem.

czy ja wiem... w sporej części API różnych mikrousług do jakich strzelam czy to z frontu czy back-endowo usługa-usluga DELETE występuje całkiem często... tak samo jak PUT, to metody jak wszystkie inne :) 

Najpierw trzeba te mikrousługi mieć. Pseudo-REST-owe i REST-owe APIs są mimo wszystko o wiele mniej popularne niż HTTP APIs. 

komentarz 8 czerwca 2020 przez Allen Obywatel (1,010 p.)

Jak mam to zrobi używając metody post? Zrobiłem coś takiego i w konsoli poprawnie wyświetla się "Delete route", a strona przeładowuje się bez błędów. Problem w tym że dokument nie jest usuwany z bazy.

router.delete('/delete/:id', (req, res) => {
  console.log('Delete route');
  Book.findOneAndDelete({ _id: req.params.id }, (err) => {
    if (err) console.warn(err);
  });
    res.redirect('/library');
});
<form action="/delete/<%= book._id %>?_method=DELETE" method="POST" class="delete-btn-form">
                <div class="delete-btn"></div>
</form>

 

komentarz 8 czerwca 2020 przez Comandeer Guru (606,120 p.)

Hmm, tak szczerze to nie powinno się wyświetlać "delete route", bo router nie powinien nawet przechwytywać tego żądania.

Dodatkowo robisz przekierowanie zanim książka zostanie usunięta z bazy. Powinieneś robić przekierowanie wewnątrz callbacku:

router.delete('/delete/:id', (req, res) => {
  console.log('Delete route');
  Book.findOneAndDelete({ _id: req.params.id }, (err) => {
    if (err) console.warn(err);
    res.redirect('/library');
  });
});

 

komentarz 8 czerwca 2020 przez Allen Obywatel (1,010 p.)
Faktycznie nie zauważyłem przekierowania w złym miejscu, jednak nadal to nie pomaga. Dlaczego router nie powinien przechwycić żądania? Używam method-override i rozumiem, że podczas wykonywania metody post z tagu form, zostaje ona nadpisana i express obsługuje delete.
komentarz 8 czerwca 2020 przez Comandeer Guru (606,120 p.)

Faktycznie, jest taki mechanizm.

Więc jedyne, co mi przychodzi do głowy, to złe id przekazywane w URL-u.

komentarz 8 czerwca 2020 przez Allen Obywatel (1,010 p.)
Id wypisane do konsoli jest identyczne jak w bazie danych. No nic będę dalej szukał błędu. Dzięki za poświęcony czas.

Podobne pytania

0 głosów
0 odpowiedzi 105 wizyt
0 głosów
0 odpowiedzi 264 wizyt
pytanie zadane 27 września 2019 w JavaScript przez DanexZ Obywatel (1,270 p.)
+2 głosów
2 odpowiedzi 672 wizyt

93,103 zapytań

142,077 odpowiedzi

321,571 komentarzy

62,445 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...