Kirjoittaja Aihe: [ ratkaistu ] Javascriptin fetch ja await-ongelma  (Luettu 3559 kertaa)

teele

  • Käyttäjä
  • Viestejä: 850
    • Profiili
Sivun

https://javascript.info/fetch

ohjeiden  mukaan javascriptin fetchin kanssa käytetään awaitia, mutta jos await-sanan laittaa Firefoxin javascriptiin, javascriptin toiminta loppuu eikä painikkeen javascript vastaa mitään esimerkiksi tässä kokeiluohjelmassa

Koodia: [Valitse]
<!DOCTYPE html>
<html>
<head>
<title> syöttökaavake, versio 01 </title>
</head>

<body style="text-align: left;">
 <h1 style="color: green;"> Syöttökaavake </h1>
 
<p> Napsauta kaavake auki </p>
<button onClick="fetch_test_fun()">Avaa kaavake </button>
<p id="prgh"></p>

 <script>
 
 function fetch_test_fun()

  alert("kokeilufunktio alkaa");
  let response = await fetch("/hello");
  //let text = await response.text(); // read response body as text
  //alert(text.slice(0, 80) + '...');           
}
 
</script>       
</body>   
</html>

<!--
https://javascript.info/fetch
 
https://javascript.info/xmlhttprequest

 -->


Fetch vaikuttaa muuten kätevämmältä kuin xhtmlrequest, jos halutaan pikku viestejä palvelimelta vaikka libhttpserveriltä. Mitä pitäsi tehdä, await pois vai xhtmlrequestin pariin vai joku muu (mukavan helppo) ratkaisu pikku viestien kyselyyn palvelimelta.


« Viimeksi muokattu: 06.02.22 - klo:16.56 kirjoittanut teele »

nm

  • Käyttäjä
  • Viestejä: 16425
    • Profiili
Vs: Javascriptin fetch ja await-ongelma
« Vastaus #1 : 04.02.22 - klo:08.56 »
Selvitä JavaScript-ongelmat selaimen kehittäjätyökalujen avulla:

1. Avaa sivu selaimeen
2. Avaa selaimen kehittäjätyökalut painamalla F12 tai Shift+Ctrl+I
3. Valitse kehittäjätyökaluista konsoli-välilehti (Console)
4. Joskus sivu täytyy päivittää, jotta kaikki virheet näkyvät oikein. F5 tai Crtl+R

Ohessa kuvakaappaus Firefoxista, joka kertoo oikean virheen, eli et ole määritellyt fetch_test_fun() -funktiota asynkroniseksi. Lisää siis rivin alkuun async-avainsana:

Koodia: [Valitse]
async function fetch_test_fun()

teele

  • Käyttäjä
  • Viestejä: 850
    • Profiili
Vs: Javascriptin fetch ja await-ongelma
« Vastaus #2 : 05.02.22 - klo:21.47 »

No niin, nyt löytyi selaimen konsolikin, aina oppii uutta :)

Selaimen mukaan pitäisi lähettää oikeanlainen otsaketeito, jotta libhttpserveriltä tullutta pyyntöä suostuttaisiin käsittelemään.

Koodia: [Valitse]
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///hello. (Reason: CORS request not http).

Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
    test_fun file:///home/k1/Documents/my_libhttpserver/testejä/testisyöttö01.html:25
    onclick file:///home/k1/Documents/my_libhttpserver/testejä/testisyöttö01.html:1


Testisyöttösivu ja libhttpserver-ohjelma ovat samassa hakemistossa. Mutta jos otsaketiedot täytyy joka tapauksessa lähettää, niin sittenhän ohjelma toimisi ehkä jopa  monipuolisemmin, jos se saadaan toimimaan.

libhttpserver-ohjelma on tällainen

Koodia: [Valitse]

#include <iostream>
#include "/home/k1/Documents/my_libhttpserver/libhttpserveri/libhttpserver/src/httpserver.hpp"

#include <iostream>
#include <fstream>
#include <string>
#include <bits/stdc++.h>

std::string filetostring(const std::string& filename)
{
  std::fstream newfile;
  std::string string1;  // tiedosto stringinä
  newfile.open(filename, std::ios::in);
  if(newfile.is_open() )
    {
      std::string row1;
      while(getline(newfile, row1))
        {
          string1 += '\n' + row1;
        } // while loppuu
    } // if loppuu
  return string1;
} // filetostring loppuu



class hello_world_resource : public httpserver::http_resource
{
  public:
    const std::shared_ptr<httpserver::http_response> render(const httpserver::http_request&);
    std::string data01, data02;
};

// Using the render method you are able to catch each type of request you receive
const std::shared_ptr<httpserver::http_response> hello_world_resource::render(const httpserver::http_request& req)
{
  std::cout << std::endl;
  std::string datapar01 = req.get_arg("data01");
  std::string datapar02 = req.get_arg("data02");
  std::string datapar03 = req.get_arg("data03"); 
  std::string datapar04 = req.get_arg("data04");
  std::string datapar05 = req.get_arg("data05");
  std::string datapar06 = req.get_arg("data06");
  std::string datapar07 = req.get_arg("data07");
  std::string datapar08 = req.get_arg("data08");
  std::string datapar09 = req.get_arg("data09");
  std::string datapar10 = req.get_arg("data10");
  std::string datapar11 = req.get_arg("data11");
 
  std::cout << "Now data 1 is:" << datapar01 << std::endl;
  std::cout << "Now data 2 is:" << datapar02 << std::endl; 
  std::cout << "Now data 3 is:" << datapar03 << std::endl;
 
  return std::shared_ptr<httpserver::http_response>(new
  //httpserver::string_response("viesti palvelimelta", 200, "text/html"));
 
  httpserver::string_response("viesti palvelimelta", 200, "text/plain"));
 
}

int main()
{          // porttinumero ja säiemäärä parametreina
  httpserver::webserver ws = httpserver::create_webserver(8080).start_method(httpserver::http::http_utils::INTERNAL_SELECT).max_threads(5);

  hello_world_resource hwr;
  ws.register_resource("/hello", &hwr, true); //  tällä kutsutaan   
  ws.start(true);  // blocking on true, non blocking olisi false
  return 0;
}



// g++ libhttpserver03.cpp -o libhttpserver03 -Wall -pedantic -L/usr/local/lib -lhttpserver -lmicrohttpd  -pthread -std=c++17


ja testisyöttösivu tällainen

Koodia: [Valitse]

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title> testisyöttö, versio 01 </title>
</head>

<body style="text-align: left;">
 <h1 style="color: green;"> Testisyöttö 01 </h1>
 
<p> Napsauta kaavake auki </p>
<button onClick="test_fun()">Avaa kaavake </button>
<p id="prgh"></p>



 <script>
 
 async function test_fun()

  alert("kokeilufunktio alkaa");
  let response = await fetch('/hello');
  let text = await response.text(); // read response body as text
  alert(text.slice(0, 80) + '...');           
}

</script>
       
</body>   
</html>


Valitettavasti netistä ei haulla "libhttpserver CORS" juurikaan taida olla apua :(

Luulo on, että libhttpserver laittaa tarvittavia otsaketietoja automaattisesti. Pitäisikö ne kuitenkin kirjoittaa johonkin kohtaan ohjelmassa?


nm

  • Käyttäjä
  • Viestejä: 16425
    • Profiili
Vs: Javascriptin fetch ja await-ongelma
« Vastaus #3 : 06.02.22 - klo:00.02 »
Selaimen mukaan pitäisi lähettää oikeanlainen otsaketeito, jotta libhttpserveriltä tullutta pyyntöä suostuttaisiin käsittelemään.

Olet nyt avannut sen testisivun suoraan tiedostosta. Tällöin törmäät CORS-rajoitteisiin, kun koodi yrittää lähettää pyyntöjä libhttpserverille. Selaimen näkökulmasta levyltä avattu HTML-tiedosto ja localhostin kautta toimiva libhttpserver eivät ole sama palvelu.

Laita libhttpserver tarjoamaan se lomakesivu jostain polusta ja avaa selaimella sieltä, niin selain ei vedä hernettä nenään CORS-sääntöjen vuoksi.

teele

  • Käyttäjä
  • Viestejä: 850
    • Profiili
Vs: Javascriptin fetch ja await-ongelma
« Vastaus #4 : 06.02.22 - klo:16.53 »
libhttpserver-ohjelmaan on nyt lisätty resursiksi sivu, joka aikaisemmin avattiin selaimella tiedostona. Tältä sivulta voi nyt pyytää fetchillä tietoja toiselta sivulta, joka on libhttpserver-ohjelman toinen resurssi, jos lisätty sivu avataan localhostin kautta ja oikeasta portista

Koodia: [Valitse]
http://localhost:8080/testisy%C3%B6tt%C3%B601.html
Palvelin on nyt tällainen

Koodia: [Valitse]

#include <iostream>
#include "/home/k1/Documents/my_libhttpserver/libhttpserveri/libhttpserver/src/httpserver.hpp"

#include <iostream>
#include <fstream>
#include <string>
#include <bits/stdc++.h>

std::string filetostring(const std::string& filename)
{
  std::fstream newfile;
  std::string string1;  // tiedosto stringinä
  newfile.open(filename, std::ios::in);
  if(newfile.is_open() )
    {
      std::string row1;
      while(getline(newfile, row1))
        {
          string1 += '\n' + row1;
        } // while loppuu
    } // if loppuu
  return string1;
} // filetostring loppuu


// resurssi vastaa esimerkiksi html-sivua asiakkaan puolella
// luokan hello_world_resource määrittely
class hello_world_resource : public httpserver::http_resource
{
  public:
    const std::shared_ptr<httpserver::http_response> render(const httpserver::http_request&);
}; // luokka hello_world_resource loppuu

// Using the render method you are able to catch each type of request you receive
// resurssilla on oma renderöijä, luokan hello_world_resource renderöijä alla
const std::shared_ptr<httpserver::http_response> hello_world_resource::render(const httpserver::http_request& req)   // pyynnön parametrien nimet rekisteröidään
{
  std::cout << std::endl;
  std::string datapar01 = req.get_arg("data01");
  std::string datapar02 = req.get_arg("data02");
  std::string datapar03 = req.get_arg("data03"); 
  std::string datapar04 = req.get_arg("data04");
  std::string datapar05 = req.get_arg("data05");
  std::string datapar06 = req.get_arg("data06");
  std::string datapar07 = req.get_arg("data07");
  std::string datapar08 = req.get_arg("data08");
  std::string datapar09 = req.get_arg("data09");
  std::string datapar10 = req.get_arg("data10");
  std::string datapar11 = req.get_arg("data11");
 
  // aputulostuksia rekiströityjen parametriniemien syötearvoista
  std::cout << "Now data 1 is:" << datapar01 << std::endl;
  std::cout << "Now data 2 is:" << datapar02 << std::endl; 
  std::cout << "Now data 3 is:" << datapar03 << std::endl;
 
  // response on asiakkaalle renderöijän asiakkaalle toimittama sivu 
  return std::shared_ptr<httpserver::http_response>(new   
  httpserver::string_response("viesti palvelimelta", 200, "text/plain"));
  //tai httpserver::string_response("viesti palvelimelta", 200, "text/html"));
} // resurssin hello_world_resource renderöijän määrittely loppuu tähän

// luokan file_response_resource määrittely
class file_response_resource : public httpserver::http_resource
{
 public:
     const std::shared_ptr<httpserver::http_response> render_GET(const httpserver::http_request&)
{
         return std::shared_ptr<httpserver::file_response>(new httpserver::file_response("testisyöttö01.html", 200, "text/html"));
     }
}; // luokka file_response_resource loppuu


int main()
{          // porttinumero ja säiemäärä parametreina
  httpserver::webserver ws = httpserver::create_webserver(8080).start_method(httpserver::http::http_utils::INTERNAL_SELECT).max_threads(5);

  hello_world_resource hwr;
  file_response_resource frr;
  ws.register_resource("/hello", &hwr, true); //  tällä kutsutaan   
  ws.register_resource("/testisyöttö01.html", &frr, true); //  tällä kutsutaan   
  ws.start(true);  // blocking on true, non blocking olisi false
  return 0;
}

ja käännös meni näin
Koodia: [Valitse]
g++ libhttpserver03.cpp -o libhttpserver03 -Wall -pedantic -L/usr/local/lib -lhttpserver -lmicrohttpd  -pthread -std=c++17

Taas taitaa ongelma olla ratkaistu tämän palstan neuvojen avulla :)

« Viimeksi muokattu: 06.02.22 - klo:16.55 kirjoittanut teele »