Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser

p.kaczmarek2 25 May 2023 04:31 1113 0
Nazwa.pl
  • Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    Ostatnio uruchamiałem prosty system raportowania pomiarów energii przez sieć WiFi ze "smart" gniazdka elektrycznego i potrzebowałem wygodnego sposobu na testowanie odbioru zapytań HTTP GET i POST. Pokażę tutaj jak można wykorzystać Node.js do tego celu. Node.js pozwala szybko i sprawnie postawić mini-serwerek HTTP na naszej maszynie, zdolny do przetwarzania tych właśnie zapytań i odpowiadania na nie w określony przez nas sposób. Przy okazji też pokażę jak można obsłużyć zapytanie POST z zawartością w formacie JSON oraz umieszczę tu krótkie przykłady wysyłania GET i POST z poziomu OpenBeken
    UWAGA: Temat zakłada, że czytelnik posiada co najmniej minimalną wiedzę jak korzystać z konsoli, jak zainstalować Node.js, czym jest serwer, HTTP, i tak dalej...

    Wysyłanie żądań HTTP
    W tym temacie zakładam, że kod wysyłki żądań (tj. klienta) już mamy, a potrzebujemy utworzyć mini serwer do testów, ale mimo to warto zaznaczyć, jak można te żądania wysyłać.
    Przykładowo można użyć biblioteki curl, która jest dostępna na wielu platformach:
    https://curl.se/
    Innym sposobem może być wysyłanie bezpośrednio z Javascript, chociażby wykonywanego w przeglądarce, możemy utworzyć plik HTML i w nim się bawić w XMLHttpRequest bądź fetch i tak dalej.
    Jeszcze innym, wyjątkowo skomplikowanym sposobem jest wysyłanie zapytań z własnego środowiska, przykładowo u mnie w OpenBeken są funkcje do wysyłania GET i POST, to właśnie te funkcje przy tworzeniu tego tematu testowałem.
    Bez względu na wybór klienta, w tym temacie przedstawię jak utworzyć prosty serwer HTTP w Node.js, zdolny do odbioru wspomnianych GET i POST.

    Obsługa HTTP GET
    Zapytanie GET jest chyba najpopularniejsze w sieci, pozwala ono zakodować argumenty w samym URL strony, nawet na naszym forum w trakcie pisania postu widzimy:
    
    https://www.elektroda.pl/rtvforum/posting.php?mode=reply&t=3977701&p=20578056
    

    Argumenty GET są po pytajniku, widzimy tutaj, że klucz "mode" ma wartość "reply", a klucz "t" ma wartość "3977701", itd.
    W ramach przykładu zrobimy prosty kalkulator. Jako argumenty będzie a i b, serwer nam zwróci ich sumę. Tworzymy plik server.js i zapisujemy:
    Code: javascript
    Log in, to see the code

    Wywołanie app.get w powyższym kodzie nie jest wysyłaniem żądania GET, leczu tworzeniem callbacka, który je obsłuży. W nim odbieramy i przetwarzamy dane. Poprzez req.query dobieramy się do argumentów z URL.
    Nawigujemy w CMD do folderu gdzie jest skrypt, i uruchamiamy go poprzez node server.js, ale pewnie otrzymamy błąd - nie ma paczki express, trzeba ją zainstalować poprzez npm install express, oto cały log:
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    Potem już node server.js poprawnie się wykonuje.
    Teraz trzeba jakoś wysłać do niego dane, sposób pierwszy - przeglądarka, otwieramy URL:
    
    http://127.0.0.1:3000/?a=13&b=87
    

    Działa:
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    W logu serwera też widzimy, że coś się dzieje:
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    To teraz może wyślijmy zapytanie GET przez CURL:
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    Oczywiście CURL musi być wcześniej zainstalowane.

    No i w ramach ciekawostki - to samo z OpenBeken:
    
    backlog setChannel 10 13; setChannel 11 87; SendGET http://localhost:3000/?a=$CH10&b=$CH11
    

    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    W OBK ten mechanizm nie wspiera na razie parsowania odpowiedzi z poziomu skryptu, służy tylko do raportowania danych do serwera.

    Obsługa HTTP POST
    Teraz będzie nieco trudniej, bo treść POST zawarta jest już w ciele zapytania, a nie w URL, więc zasadniczo nie widać jej na pierwszy rzut oka. Oczywiście POST też występuje nawet na naszym forum, przykładowo jak się logujemy bądź rejestrujemy, wtedy nasz login i hasło jest właśnie wysyłane zapytaniem POST.
    Post dodatkowo wprowadza tzw. Content-Type, czyli typ zawartości zapytania, może to być przykładowo czysty tekst, strumień binarny bądź właśnie format JSON.
    Jak wygląda JSON? Przykładowy JSON poniżej:
    Code: json
    Log in, to see the code

    JSON może przechowywać obiekty wraz z parami klucz-wartość oraz tablice.
    Przepiszmy w ramach przykładu nasz kod tak, by korzystał z formatu JSON ale wciąż wykonywał tę samą operację.
    Code: javascript
    Log in, to see the code

    Tak jak wcześniej tworzyliśmy callback w app.get, tutaj tak samo tworzymy obsługę post w app.post. Teraz a i b bierzemy z tekstu w formacie JSON, z ciała zapytania.
    Teraz trzeba go przetestować. Zacznijmy od metody z CURL:
    
    curl -X POST -H "Content-Type: application/json" -d "{\"a\": 13, \"b\": 87}" http://localhost:3000/
    

    Przełącznik X ustawia typ zapytania, H dodaje nagłówek Content-Type określający co wysyłamy, -d ustawia dane. Cudzysłów z \ to tzw. escape sequence, pozwala umieścić cudzysłów w treści zapytania bez rzeczywistego zamykania cudzysłowia określającego blok danych.
    Wszystko działa:
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    W ramach przykładu, zobaczmy jak można to samo wysłać z samego Javascript - z prostego pliku HTML, uruchamianego w przeglądarce, bez stawiania serwera. Każdy może to wygodnie odpalić:
    Code: html
    Log in, to see the code

    Niestety ten skrypt nie wykona się poprawnie. Pojawia się tutaj problem z CORS (Cross-Origin Resource Sharing).
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    Treść błędu jako tekst:
    
    p://localhost:3000/' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    test.html:18 
          
            POST http://localhost:3000/ net::ERR_FAILED
    sendSumRequest @ test.html:18
    onclick @ test.html:23
    

    CORS blokuje zewnętrzne zapytania Ajax w celu zwiększenia bezpieczeństwa zasobów, musimy je odblokować. Modyfikujemy serwer:
    Code: javascript
    Log in, to see the code

    Jeszcze nie odpalamy, inaczej dostalibyśmy błąd:
    
    Error: Cannot find module 'cors'
    

    więc instalujemy brakującą paczkę:
    
    npm install cors
    

    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    Po tej zmianie (i restarcie serwera) skrypt działa:
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    No i jeszcze w ramach ciekawostki to samo z OpenBeken:
    
    backlog setChannel 10 13; setChannel 11 87; SendPOST http://localhost:3000/ 3000 "application/json" "{ \"a\":$CH10, \"b\":$CH11 }"
    

    Kod specjalnie, w ramach demonstracji, ustawia kanały na 13 i 87 a potem wykorzystuje ich wartości przy generacji JSON.
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser
    Rezultat:
    Node.js jako mini serwer HTTP, testowanie zapytań GET i POST, JSON, express, body-parser

    Podsumowanie
    Node.js oferuje bardzo wygodny zbiór narzędzi i bibliotek do tworzenia aplikacji typu server-side w języku Javascript. Tutaj pokazałem jak można je wykorzystać do utworzenia mini-serverka do testów odbioru zapytań GET i POST, gdyż docelowo serwer zamierzam postawić na jednym z darmowych hostingów WWW dostępnych w sieci a same zapytania będę odbierać już na poziomie PHP, ale nic nie stoi na przeszkodzie by wykorzystać Node.js inaczej, wszystko wedle uznania.
    W podobny sposób można też dostać się bezpośrednio do bazy danych, np. do InfluxDB, dzięki użyciu ich HTTP API:
    https://archive.docs.influxdata.com/influxdb/v1.2/guides/writing_data/
    Być może wkrótce pokażę jakiś konkretny przykład realizacji loggera temperatury czy tam napięcia/prądu/mocy w oparciu o pokazane tu mechanizmy.

    Cool? Ranking DIY
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • Nazwa.pl