Wysyłanie JSON do serwera i pobieranie w zamian JSON, bez JQuery

115

Muszę wysłać JSON (który mogę zdefiniować) na serwer i pobrać wynikowy JSON po stronie użytkownika, bez używania JQuery.

Jeśli powinienem użyć GET, jak przekazać JSON jako parametr? Czy istnieje ryzyko, że potrwa to zbyt długo?

Jeśli powinienem używać POST, jak ustawić odpowiednik onloadfunkcji w GET?

Czy powinienem użyć innej metody?

UWAGA

To pytanie nie dotyczy wysyłania prostego AJAX. Nie należy go zamykać jako duplikat.

Jérôme Verstrynge
źródło
Musisz użyć XMLHttpRequest. Niezależnie od nazwy, możesz jej użyć dla danych JSON (i tak właśnie robi to jQuery w tle).
elixenide
2
OPUBLIKOWAŁbym dane. Spójrz na to: youmightnotneedjquery.com . Pokazuje, jak możesz pobierać / publikować dane za pomocą vanilla JS.
HaukurHaf
1
@Ed Cottrell Przywołane pytanie nie ma z tym nic wspólnego. Odniesienie dotyczy (TYLKO) sendingżądania AJAX, co jest dość ogólną rzeczą. Ten prosi o sendingale iw receiving JSONczystym JavaScript. Ponadto, aby odesłać ten JSON z powrotem, musisz wiedzieć, jak rozwiązać tę część problemu, server-sidektóra jest inną rzeczą, o której nie wspomniano w przywoływanym pytaniu.
hex494D49
1
@Ed Cottrell Pytanie, do którego się odnosiłeś, nie ma zatwierdzonej odpowiedzi i używa starych metod do tworzenia żądania Ajax. Nie daje pełnej odpowiedzi na to pytanie. Moje pytanie jest bardziej subtelne niż tradycyjny Ajax POST lub GET. Przegapiłeś sens.
Jérôme Verstrynge
1
@JVerstry onreadystatechangejest tym, czego używasz do emulacji onload, jak pokazano w zaakceptowanej odpowiedzi poniżej. Do parsowania wystarczy użyć JSON.parse()(ponownie, jak pokazano w odpowiedzi), ale zakładałem, że już o tym wiesz, ponieważ wspomniałeś o ciągnieniu w pytaniu. Próbowałem ci pomóc, wskazując na nie jedno, ale dwa pytania dotyczące tych punktów. Jest oczywiście pewna różnica - rzadko dwa pytania są dokładnie identyczne - ale jest to trywialne, jeśli już wiesz, jak zdefiniować i przeanalizować JSON. To powiedziawszy, ponieważ ty i @ hex494D49 nie zgadzacie się, nominuję to do ponownego otwarcia.
eliksenid

Odpowiedzi:

221

Wysyłanie i odbieranie danych w formacie JSON metodą POST

// Sending and receiving data in JSON format using POST method
//
var xhr = new XMLHttpRequest();
var url = "url";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var json = JSON.parse(xhr.responseText);
        console.log(json.email + ", " + json.password);
    }
};
var data = JSON.stringify({"email": "[email protected]", "password": "101010"});
xhr.send(data);

Wysyłanie i odbieranie danych w formacie JSON metodą GET

// Sending a receiving data in JSON format using GET method
//      
var xhr = new XMLHttpRequest();
var url = "url?data=" + encodeURIComponent(JSON.stringify({"email": "[email protected]", "password": "101010"}));
xhr.open("GET", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var json = JSON.parse(xhr.responseText);
        console.log(json.email + ", " + json.password);
    }
};
xhr.send();

Obsługa danych w formacie JSON po stronie serwera przy użyciu PHP

<?php
// Handling data in JSON format on the server-side using PHP
//
header("Content-Type: application/json");
// build a PHP variable from JSON sent using POST method
$v = json_decode(stripslashes(file_get_contents("php://input")));
// build a PHP variable from JSON sent using GET method
$v = json_decode(stripslashes($_GET["data"]));
// encode the PHP variable to JSON and send it back on client-side
echo json_encode($v);
?>

Limit długości żądania HTTP Get zależy zarówno od serwera, jak i używanego klienta (przeglądarki) i wynosi od 2kB do 8kB. Serwer powinien zwrócić status 414 (żądanie-URI zbyt długie), jeśli identyfikator URI jest dłuższy niż serwer może obsłużyć.

Uwaga Ktoś powiedział, że mogę używać nazw stanów zamiast ich wartości; innymi słowy, mógłbym użyć xhr.readyState === xhr.DONEzamiast xhr.readyState === 4. Problem polega na tym, że Internet Explorer używa różnych nazw stanów, więc lepiej jest używać wartości stanu.

hex494D49
źródło
4
Powinien być xhr.status === 200.
napisano
Używam tego samego kodu do wysyłania danych JSON do REST API, które jest hostowane na lokalnym hoście, ale otrzymuję błądXHR failed loading: POST
viveksinghggits
@viveksinghggits Najpierw sprawdź, czy powyższy kod działa na twoim lokalnym hoście. Jeśli tak (i ​​powinno działać), problem musi być gdzieś po stronie twojego serwera; jeśli nie, daj mi znać, a ja to sprawdzę. W ten sposób, nie mając nic z twojego kodu, nie mogę ci pomóc.
hex494D49,
@ hex494D49 tak wdzięczny za twoją odpowiedź, tak naprawdę odpalałem XHR na działanie przesyłania formularza, kiedy zmieniłem go tak, aby był uruchamiany przez zdarzenie kliknięcia na. Wystąpił błąd CORS, który jest zrozumiały i zmieniam w tym celu kod po stronie serwera. Pisałem o tym tutaj medium.com/@viveksinghggits/ ...
viveksinghggits
6

Korzystanie z nowego pobierania interfejsu API :

const dataToSend = JSON.stringify({"email": "[email protected]", "password": "101010"});
let dataReceived=""; 
fetch("",{credentials:'same-origin',mode:'same-origin',method:"post",body:dataToSend})
              .then(resp => {
                if(resp.status==200){
                   return resp.json()
                }else{
                    console.log("Status: "+resp.status);
                    return Promise.reject("server")
                }
              })
           .then(dataJson =>{
                 dataReceived = JSON.parse(dataJson);
             })
              .catch(err =>{
                if(err=="server")return
                console.log(err);
            })
            
 console.log(`Received: ${dataReceived}`)                
Musisz poradzić sobie z wysłaniem przez serwer innego statusu niż 200 (ok), powinieneś odrzucić ten wynik, ponieważ jeśli zostawisz go pustym, spróbuje przeanalizować json, ale nie ma, więc wyrzuci błąd

John Balvin Arias
źródło
1
Używasz JSON.stringifydwa razy.
Shukant Pal